home *** CD-ROM | disk | FTP | other *** search
/ Chip: Special XP & Vista / Chip Spesial XP & Vista.iso / 1_Audio_Video / MediaCell_Mobile_Video_Converter / MediaCellMobileVideoConverterSetupFull.exe / VEMODE.hta < prev    next >
Text File  |  2008-04-03  |  144KB  |  4,566 lines

  1. <HTML>
  2. <HEAD>
  3. <!-----------------------------------------------------------------
  4. MediaCell Mobile Video Converter
  5. ------------------------------------------------------------------>
  6. <hta:application
  7.     ID="VMHta"
  8.     APPLICATIONNAME="MediaCell Mobile Video Converter"
  9.     VERSION="1.1b"
  10.     BORDER="thin" thick | dialog | none  | thin
  11.     BORDERSTYLE="normal" | complex | raised  | static  | sunken
  12.     CAPTION="YES"
  13.     ICON="MediaCell.ico"
  14.     CONTEXTMENU="NO"
  15.     SCROLL="NO"
  16.     SCROLLFLAT = "yes"    
  17.     MAXIMIZEBUTTON="NO"
  18.     MINIMIZEBUTTON="YES"
  19.     SHOWINTASKBAR="YES"
  20.     SINGLEINSTANCE="YES"
  21.     SYSMENU="YES"
  22.  
  23.     WINDOWSTATE="normal" | maximize | minimize
  24. />
  25.  
  26. <SCRIPT LANGUAGE="JScript" FOR="Player1" EVENT="playStateChange(NewState)" type="text/javascript">
  27. // Event Handler for Media Player
  28. switch (NewState)
  29. {
  30.     case 0: // Unknown
  31.         break;
  32.  
  33.     case 8: // Finished
  34.         isPlayerDone = true;
  35.  
  36.     case 1: // Stoppped
  37.         isPlayerPaused = false;
  38.         isPlayerStopped = true;
  39.         break;
  40.  
  41.     case 2: // Paused
  42.         isPlayerPaused = true;
  43.         isPlayerStopped = false;
  44.         break;
  45.  
  46.     case 3: // Playing
  47.         isPlayerPaused = false;
  48.         isPlayerStopped = false;
  49.         if (whichPlayerInitializing)
  50.         {
  51.             whichPlayerInitializing.controls.pause();
  52.             if (whichPlayerInitializing.playState == 3)
  53.                 whichPlayerInitializing.controls.stop();
  54.             whichPlayerInitializing = null;
  55.         }
  56.         break;
  57.  
  58.     case 6: // Buffering
  59.         isPlayerStopped = false;
  60.         break;
  61.  
  62.     case 7:  // Waiting
  63.  
  64.     case 9:  // Transitioning
  65.  
  66.     case 11: // Reconnecting
  67.         if (!isPlayerDone)
  68.             isPlayerStopped = false;
  69.         break;
  70. }
  71. </script>
  72. <script type="text/javascript" src="vm.htj"></script>
  73. <script language="javascript">
  74.  
  75. var menuHasFocus = false;
  76. var lastAlt = false;
  77. var localPath, run, inTarget='1', inRatio, recDuration, partDuration;
  78. var isMultiVOB = false;
  79. var isSingleVOB = false;
  80. var isSingle2ndPass = false;
  81. var dvdDuration = "";
  82. var outTitle = "MediaCell Mobile Video Converter";
  83. var outPath = ".";
  84. var defaultOutPath = "C:\\MediaCell\\";
  85. var streams, nStreams, langArray, vobPath, subArray;
  86. var OvidCodec,Oresolution,Oframerate,Obitrate,OaudCodec,Ochannels,OaudRate,OaudBR,Oformat,Ovol="100", OlockRatio;
  87. var OcropLeft,OcropRight,OcropTop,OcropBottom;
  88. var cropWinWidth, cropWinHeight, cropWinTop, cropWinLeft;
  89. var mdHeight=320, mdWidth=320; // Screen Resolution of selected device
  90. var shotPos=100;
  91. var lastShotPos=-1;
  92. var encTimer=null;
  93. var startTm=null;
  94. var lastElapsed=0;
  95. var cropPreset=0;
  96. var multi_num, multi_pass;
  97. var devices = null;
  98. var currDevice=-1,currDevCrop=-1,currDevPres=-1, currDevName, currDevLabel;
  99. var wHelp=null;
  100. var ffInputFile='';
  101. var lastDevice='';
  102. var lastVMRun='';
  103. var VMMode='';
  104. var inputFormat='';
  105. var audioMap=1,videoMap=0;
  106. var pmTimer=null;
  107. var progPos, lastPartProgPos=0, lastTStamp="";
  108. var numInQ=0, batchQ, batchProgress=-1, masterBatchIdx, batchCurrFile=0;
  109. var systemBusy=false;
  110. var indexComplete=false;
  111. var ssAVSfile="";
  112. var needTocheckAVStrack=false, checkedAVStrack=false;
  113. var fileInput="";
  114. var debugMode=false;
  115. var subtitleAsked=false;
  116.  
  117. if (window.resizeTo)
  118. {
  119.     if (screen.deviceXDPI > 96)
  120.         window.resizeTo(730,588);
  121.     else
  122.         window.resizeTo(730,588);
  123. }
  124.  
  125. var appPath = (VMHta) ? VMHta.commandLine : '';
  126. if (!appPath)
  127.     alert("This program needs to run on your local PC.");
  128.  
  129. function popFileOpen()
  130. {
  131.     ff.vFile.click();
  132. }
  133.  
  134. function about()
  135. {
  136.     alert("MediaCell v2.55  by MediaCell\n\nCopyright(c) 2006-2007\n\n"
  137.          +"MediaCell is a Video Encoder for Mobile Devices.\n"
  138.          +"Web site    : http:\/\/www.mediacell.com/");
  139. }
  140.  
  141. function openHelp(url)
  142. {
  143.     if (wHelp && !wHelp.closed)
  144.         wHelp.close();
  145.  
  146.     wHelp = window.open(url,'wHelp','width=600,height=400,top=80,left=80,screenX=80,screenY=80,scrollbars=1,titlebar=no,toolbar=0,menubar=0,location=0,personalbar=0,directories=0,status=0,resizable=1');
  147.     setTimeout("wHelp.focus()",500);
  148. }
  149.  
  150. // Adds a preceding 0 to numbers 1..9 for timestamps
  151. function preZero(n)
  152. {
  153.     return (((''+n).length < 2) ? '0' : '') + n;
  154. }
  155.  
  156. // Timestamp for an encoding date
  157. function getEncDate()
  158. {
  159.     var d = new Date();
  160.     return( d.getYear()+'-'+ preZero(d.getMonth() + 1)+'-'+ preZero(d.getDate())
  161.         +' '+ preZero(d.getHours()) +':'+ preZero(d.getMinutes()) +':'+ preZero(d.getSeconds()));
  162. }
  163.  
  164. // Check for multi-part DVD VOBs
  165. function checkMultiPartDVD(fName)
  166. {
  167.     var data, num, str, ch, vPos, nTitles, tSec, lIdx, ifo;
  168.     isMultiVOB = false;
  169.     isSingleVOB = false;
  170.     isSingle2ndPass = false;
  171.  
  172.     if (VMMode != 'EZ') oF.splitBtn.style.visibility = "visible";
  173.     oF.splitTo.value = "";
  174.  
  175.     var m = fName.match(/^(.*\\?)(vts_\d+_)(\d+)\.vob$/i);
  176.     if (m && parseInt(m[3]) > 0)
  177.     {
  178.         var answer = askYesNo("This file is part of a DVD title.\n\nDo you want to encode this DVD title as a single video?\n");
  179.         if (answer == 7) // No
  180.             isSingleVOB = true;
  181.         else if (answer == 6) // Yes
  182.             isMultiVOB = true;
  183.         else if (answer == 2) // Cancel
  184.             return "";
  185.  
  186.         if (isSingleVOB || isMultiVOB)
  187.         {
  188.             // Get info from the .IFO file if found
  189.             window.ifoFile = m[1] + m[2] +"0.IFO";
  190.             window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  191.  
  192.             try
  193.             {
  194.                 ifo = pfso.Opentextfile(ifoFile);
  195.             }
  196.             catch(e)
  197.             {
  198.                 ifo = null;
  199.             }
  200.             if (!ifo || ifo.atEndOfStream)
  201.             {
  202.                 isMultiVOB = false;
  203.                 isSingleVOB = false;
  204.                 alert("Unable to find "+ ifoFile +"\n\nThis file is required to process the whole DVD");
  205.                 return fName;
  206.             }
  207.  
  208.             // Get the Audio Languages
  209.             vPos = 0x205;
  210.             ifo.Skip(vPos);
  211.             data = ifo.Read(1); vPos++;
  212.  
  213.             str="";
  214.             lIdx = 0;
  215.             langArray = new Array();
  216.  
  217.             // Fix default 2 channel mode
  218.             if (data.charCodeAt(0) == 1) data = String.fromCharCode(193);
  219.  
  220.             while (data.charCodeAt(0) >= 193)
  221.             {
  222.                 ch = " "+ (data.charCodeAt(0)-191) +"ch";
  223.                 data = ifo.Read(2); vPos += 2;
  224.                 str += (!langCodeToStr(data)) ? ch +"|" : langCodeToStr(data) + ch +"|";
  225.                 langArray[lIdx] = (!langCodeToStr(data)) ? ch : (langCodeToStr(data) + ch);
  226.                 ifo.Skip(5);  vPos += 5;
  227.                 data = ifo.Read(1); vPos += 1;
  228.                 lIdx++;
  229.             }
  230.             
  231.             // Let's get the subtitle languages
  232.             subArray = null;
  233.             ifo.Skip(0x255 - vPos); vPos = 0x255;
  234.             data = ifo.Read(1); vPos++;
  235.             if (hexStrToDec(data) > 0)
  236.             {
  237.                 lIdx = 0;
  238.                 subArray = new Array();
  239.                 data = ifo.Read(1); vPos++;
  240.                 while (data.charCodeAt(0) == 1)
  241.                 {
  242.                     ifo.Skip(1);  vPos += 1;
  243.                     data = ifo.Read(2); vPos += 2;
  244.                     subArray[lIdx] = (!langCodeToStr(data)) ? "n/a" : data;
  245.                     ifo.Skip(2);  vPos += 2;
  246.                     data = ifo.Read(1); vPos += 1;
  247.                     lIdx++;
  248.                 }
  249.             }
  250.  
  251.             // Now let's get the duration of the first title
  252.             inTarget = 0;
  253.             ifo.Skip(0x1000 - vPos); vPos = 0x1000;
  254.             data = ifo.Read(2); vPos += 2;
  255.             nTitles = hexStrToDec(data);
  256.  
  257.             var tPos = new Array(nTitles);
  258.  
  259.             ifo.Skip(0x100c - vPos); vPos = 0x100c;
  260.             for (var t=0; t < nTitles; t++)
  261.             {
  262.                 data = ifo.Read(4); vPos += 4;
  263.                 tPos[t] = hexStrToDec(data) + 4;
  264.                 ifo.Skip(4); vPos += 4;
  265.             }
  266.  
  267.             for (var t=0; t < nTitles; t++)
  268.             {
  269.                 if (tPos[t] > 0)
  270.                 {
  271.                     ifo.Skip(0x1000 + tPos[t] - vPos); vPos = 0x1000 + tPos[t];
  272.                     data = ifo.Read(3); vPos += 3;
  273.                     str = Dec2Hex(data.charCodeAt(0)) +":"+ Dec2Hex(data.charCodeAt(1)) +":"+ Dec2Hex(data.charCodeAt(2));
  274.                     tSec = (parseInt(Dec2Hex(data.charCodeAt(0)))*60*60 + parseInt(Dec2Hex(data.charCodeAt(1)))*60 + parseInt(Dec2Hex(data.charCodeAt(2))));
  275.                     inTarget += tSec;
  276.                 }
  277.             }
  278.  
  279.             var remTime = inTarget, num;
  280.             num = Math.floor(remTime / (60*60))
  281.             str = preZero(num) +":";
  282.             remTime -= num*60*60;
  283.             num = Math.floor(remTime / (60))
  284.             str += preZero(num) +":";
  285.             remTime -= num*60;
  286.             str += preZero(remTime);
  287.  
  288.             dvdDuration = str;
  289.  
  290.             ifo.Close();
  291.             if (isMultiVOB)
  292.                 return m[1] + m[2];
  293.         }
  294.     }
  295.  
  296.     oF.recStart.className = "";
  297.     oF.recStart.readOnly = false;
  298.     oF.recEnd.className = "";
  299.     oF.recEnd.readOnly = false;
  300.  
  301.     return fName;
  302. }
  303.  
  304. // Decode a hex string to decimal
  305. function hexStrToDec(str)
  306. {
  307.     var num, dec=0;
  308.     var factor = 1;
  309.     for (i=str.length-1;i >= 0; i--)
  310.     {
  311.         num = str.charCodeAt(i);
  312.         if (num == 8217) num = 146;  // Fix special character
  313.         if (num > 256) return -999;  // FIX THIS ?
  314.  
  315.         dec += num * factor;
  316.         factor *= 16*16;
  317.     }
  318.     return dec;
  319. }
  320.  
  321. function Dec2Hex(Decimal)
  322. {
  323.     return Decimal.toString(16).toUpperCase();
  324. }
  325.  
  326. // Return the text representation of a language code
  327. function langCodeToStr(code)
  328. {
  329.     var isoLang = new Array("aa","Afar","ab","Abkhazian","af","Afrikaans","am","Amharic","ar","Arabic","as","Assamese","ay","Aymara","az","Azerbaijani","ba","Bashkir","be","Byelorussian","bg","Bulgarian","bh","Bihari","bi","Bislama","bn","Bengali Bangla","bo","Tibetan","br","Breton","ca","Catalan","co","Corsican","cs","Czech","cy","Welsh","da","danish","de","german","dz","Bhutani","el","Greek","en","English","eo","Esperanto","es","Spanish","et","Estonian","eu","Basque","fa","Persian","fi","Finnish","fj","Fiji","fo","Faeroese","fr","French","fy","Frisian","ga","Irish","gd","Scots Gaelic","gl","Galician","gn","Guarani","gu","Gujarati","ha","Hausa","hi","Hindi","hr","Croatian","hu","Hungarian","hy","Armenian","ia","Interlingua","ie","Interlingue","ik","Inupiak","in","Indonesian","is","Icelandic","it","Italian","iw","Hebrew","ja","Japanese","ji","Yiddish","jw","Javanese","ka","Georgian","kk","Kazakh","kl","Greenlandic","km","Cambodian","kn","Kannada","ko","Korean","ks","Kashmiri","ku","Kurdish","ky","Kirghiz","la","Latin","ln","Lingala","lo","Laothian","lt","Lithuanian","lv","Latvian, Lettish","mg","Malagasy","mi","Maori","mk","Macedonian","ml","Malayalam","mn","Mongolian","mo","Moldavian","mr","Marathi","ms","Malay","mt","Maltese","my","Burmese","na","Nauru","ne","Nepali","nl","Dutch","no","Norwegian","oc","Occitan","om","(Afan), Oromo","or","Oriya","pa","Punjabi","pl","Polish","ps","Pashto, Pushto","pt","Portuguese","qu","Quechua","rm","Rhaeto-Romance","rn","Kirundi","ro","Romanian","ru","Russian","rw","Kinyarwanda","sa","Sanskrit","sd","Sindhi","sg","Sangro","sh","Serbo-Croatian","si","Singhalese","sk","Slovak","sl","Slovenian","sm","Samoan","sn","Shona","so","Somali","sq","Albanian","sr","Serbian","ss","Siswati","st","Sesotho","su","Sudanese","sv","Swedish","sw","Swahili","ta","Tamil","te","Telugu","tg","Tajik","th","Thai","ti","Tigrinya","tk","Turkmen","tl","Tagalog","tn","Setswana","to","Tonga","tr","Turkish","ts","Tsonga","tt","Tatar","tw","Twi","uk","Ukrainian","ur","Urdu","uz","Uzbek","vi","Vietnamese","vo",
  330. "Volapuk","wo","Wolof","xh","Xhosa","yo","Yoruba","zh","Chinese","zu","Zulu");
  331.  
  332.     for(i=0; i < isoLang.length; i+=2)
  333.     {
  334.         if (isoLang[i]==code)
  335.             return isoLang[i+1];
  336.     }
  337.     isoLang = null;
  338. }
  339.  
  340. // Scan the input file and get it's properties using MediaInfo
  341. function scanFile(explicitFile)
  342. {
  343.     var fName = (explicitFile) ? explicitFile : ff.vFile.value;
  344.     if (!fName)
  345.     {
  346.         ff.txtOut.value = "No file to load.";
  347.         return;
  348.     }
  349.     var fileToScan = fName;
  350.     ffInputFile = "";
  351.  
  352.     // Reset MediaCell
  353.     f.reset();
  354.     window.secOutPath=null;
  355.     lastShotPos=-1;
  356.     indexComplete=false;
  357.     needTocheckAVStrack=false;
  358.     checkedAVStrack=false;
  359.     subtitleAsked=false;
  360.     window.AVSfile=null;
  361.     ssAVSfile="";
  362.     ff.txtOut.value = "";
  363.     da.instLink.style.visibility = "hidden";
  364.     f.duration.value = "Loading...";
  365.     outPath = ".";
  366.     clearSplit();
  367.     document.getElementById("langLbl").style.visibility = "hidden";
  368.     f.lang.style.visibility = "hidden";
  369.     ssHide(f.lang);
  370.     document.getElementById("subtLbl").style.visibility = "hidden";
  371.     f.subt.style.visibility = "hidden";
  372.     ssHide(f.subt);
  373.     document.getElementById("suboLbl").style.visibility = "hidden";
  374.     document.getElementById("suboFld").style.visibility = "hidden";
  375.  
  376.     // Check for multi-part DVD VOBs
  377.     fName = checkMultiPartDVD(fName);
  378.     if (!fName)
  379.     {
  380.         ff.txtOut.value = "Encoding cancelled.";
  381.         return;
  382.     }
  383.  
  384.     if (isMultiVOB)
  385.     {
  386.         ff.txtOut.value = "DVD title selected";
  387.         fileToScan = fName +"1.vob";
  388.         fileInput = fileToScan;
  389.     }
  390.     else if (isSingleVOB)
  391.     {
  392.         fileToScan = fName.replace(/\d+\.vob/i,"") +"1.vob";
  393.         fileInput = fileToScan;
  394.     }
  395.     else
  396.         fileInput = fName;
  397.  
  398.     try
  399.     {
  400.         window.encodeShell = new ActiveXObject( "WScript.shell" );
  401.         encodeShell.run( '%comspec% /c .\\mediainfo\\mediainfo.exe -f "'+ fileToScan +'" > .\\minfo.log 2>&1', 0, false );
  402.         window.outStream=null;
  403.      }
  404.      catch(e)
  405.      {
  406.          alert("Scanning File Error: "+ e.message);
  407.          return;
  408.      }
  409.  
  410.      window.scanLog = String();
  411.  
  412.      setTimeout("readScan(1)", 1000);
  413. }
  414.  
  415. // Scan the input file and get additional properties using MediaCellEngine
  416. function scanFile2(explicitFile)
  417. {
  418.     var fName = (explicitFile) ? explicitFile : fileInput;
  419.     if (!fName) return;
  420.  
  421.      var fileToScan = (isMultiVOB || isSingleVOB) ?  fName.replace(/\d+\.vob/i,"") +"1.vob" : fName;
  422.  
  423.     ffInputFile = fileToScan; //checkAVS(fileToScan, false, true);
  424.  
  425.     try
  426.     {
  427.         window.encodeShell = new ActiveXObject( "WScript.shell" );
  428.         encodeShell.run( '%comspec% /c .\\Engine\\MediaCellInfo.exe -i "'+ ffInputFile +'" > .\\mediainfo.log 2>&1', 0, false );
  429.         for(i=0;i<1000;i++);
  430.         window.outStream=null;
  431.      }
  432.      catch(e)
  433.      {
  434.          alert("Scanning Step 2 Error: "+ e.message);
  435.          return;
  436.      }
  437.  
  438.      window.scanLog = String();
  439.      setTimeout("readScan2(1)", 1000);
  440. }
  441.  
  442.  
  443. // Save user settings into the registry
  444. function saveSetting(setName, setValue)
  445. {
  446.     var reg = new ActiveXObject( "WScript.shell" );
  447.     reg.RegWrite("HKCU\\Software\\MediaCell\\", 1, "REG_BINARY");
  448.     reg.RegWrite("HKCU\\Software\\MediaCell\\"+ setName, setValue, "REG_SZ");
  449.     reg=null;
  450. }
  451.  
  452. // Load user settings from the registry
  453. function loadSetting(setName)
  454. {
  455.     var reg = new ActiveXObject( "WScript.shell" );
  456.     var result = reg.RegRead ("HKCU\\Software\\MediaCell\\"+ setName);
  457.     reg=null;
  458.     return  result;
  459. }
  460.  
  461. // Retrieve the name of the WAV file created by DGIndex
  462. function getWavFileName()
  463. {
  464.     if (!window.secOutPath)
  465.         setSecondaryOutPath();
  466.     
  467.     window.wavFileName = "";
  468.  
  469.     var wavFile, closeFSO=true;
  470.     try
  471.     {
  472.         if (window.pfso)
  473.             closeFSO = false;
  474.         else
  475.             window.pfso = new ActiveXObject("Scripting.FileSystemObject");
  476.         var fol = pfso.GetFolder(secOutPath);
  477.         var fe = new Enumerator(fol.files);
  478.         for (; !fe.atEnd(); fe.moveNext())
  479.         {
  480.             wavFile = ""+ fe.item();
  481.             if (wavFile.substr(0,indexFile.length) == indexFile && wavFile.search(/\.wav$/i) > 0)
  482.             {
  483.                 window.wavFileName = wavFile;
  484.                 fol=null;
  485.                 if (closeFSO) pfso=null;
  486.                 fe=null;
  487.                 return;
  488.             }
  489.         }
  490.         alert("Error: unable to find audio file.");
  491.         fol=null;
  492.         fe=null;
  493.     }    
  494.      catch(e)
  495.      {
  496.          alert("Error getting audio file. "+ e.message);
  497.      }
  498.      if (closeFSO) pfso=null;
  499. }
  500.  
  501. // Check if we need to use AVSredirect to read the input file
  502. function checkAVS(fToScan, doReuse, isInfoOnly)
  503. {
  504.     // Use AVS for TiVo and WMV/ASF
  505.     var isTiVo = (fToScan.search(/\.TiVo$/i) > 0);
  506.     var isWMV = (!isInfoOnly && (fToScan.search(/\.asf$/i) > 0 || fToScan.search(/\.wmv$/i) > 0 || fToScan.search(/\.dvr-ms$/i) > 0 || f.vCodec.value.search(/^wmv/)==0));
  507.     var isMOV = (!isInfoOnly && fToScan.search(/\.mov$/i) > 0);
  508.     var isMP4 = (!isInfoOnly && fToScan.search(/\.mp4$/i) > 0);
  509.     var isDV = (!isInfoOnly && f.vCodec.value.search(/^dvsd$/i) == 0);
  510.     var extSubtitles="", subIsText = true;
  511.  
  512.     // See if there are usable subtitles
  513.     var closeFSO=false;
  514.     if (!subtitleAsked && (!isInfoOnly || isTiVo) && (!doReuse || !window.AVSfile))
  515.     {
  516.         try
  517.         {
  518.             if (!window.pfso)
  519.             {
  520.                 closeFSO=true;
  521.                 window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  522.             }
  523.             var pref = fToScan.replace(/\.[^.]+$/,"");
  524.             if (pfso.FileExists(pref +".srt"))
  525.                 extSubtitles = pref +".srt";
  526.             else if (pfso.FileExists(pref +".smi"))
  527.                 extSubtitles = pref +".smi";
  528.             else if (pfso.FileExists(pref +".sub") && pfso.FileExists(pref +".idx") )
  529.             {
  530.                 extSubtitles = pref;
  531.                 subIsText = false;
  532.             }
  533.  
  534.             if (extSubtitles)
  535.             {
  536.                 var answer = askYesNo("Do you want to include the subtitles?");
  537.                 if (answer != 6) // If not Yes
  538.                 {
  539.                     extSubtitles = "";
  540.                     subtitleAsked = true;
  541.             }
  542.         }
  543.         }
  544.         catch(e) 
  545.         {
  546.             if (debugMode)
  547.                 alert("Looking for subtitle files: "+ e.message);
  548.         }
  549.     }
  550.  
  551.     if (isTiVo || isWMV || isDV || isMP4 || isMOV || extSubtitles)
  552.     {
  553.         // Fix for Sonic codec error
  554.         if (isTiVo && !window.SonicChecked)
  555.         {
  556.             var reg = new ActiveXObject( "WScript.shell" );
  557.             try
  558.             {
  559.                 if (reg.RegRead("HKLM\\SOFTWARE\\Sonic\\CineMaster DS DVD\\2.5\\RegApp"))
  560.                 {
  561.                     reg.RegWrite("HKLM\\SOFTWARE\\Sonic\\CineMaster DS DVD\\2.5\\VideoDecoder\\ALLOWALLRENDERERS", "1", "REG_DWORD");
  562.                 }
  563.             }
  564.             catch(e) 
  565.             {
  566.                 if (debugMode)
  567.                     alert("Error with Sonic check: "+ e.message)
  568.             }
  569.             reg=null;
  570.             window.SonicChecked = true;
  571.         }    
  572.  
  573.         if (doReuse && window.AVSfile)
  574.         {
  575.             if (closeFSO) pfso=null;
  576.             return AVSfile;
  577.         }
  578.  
  579.         // Flag that we will need to re-confirm the A/V tracks from the AVS instead of the FFinfo
  580.         if (!checkedAVStrack && (isWMV || isDV || isMP4))
  581.             needTocheckAVStrack = true;
  582.  
  583.         if (!window.secOutPath)
  584.             setSecondaryOutPath();
  585.  
  586.         window.AVSfile = fToScan.replace(/\.[a-zA-Z0-9\-]+$/,".avs")
  587.         var m = oF.fName.value.match(/\\([^\\]+)\.[^.]+$/);
  588.         if (m)
  589.             AVSfile = secOutPath +"\\"+ m[1] +".avs"; // Preferred name and location for AVS file
  590.  
  591.         try
  592.         {
  593.             if (!window.pfso)
  594.             {
  595.                 closeFSO=true;
  596.                 window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  597.             }
  598.             var cf = pfso.Opentextfile(AVSfile, 2, true, 0);  // Writing - Create if needed - ASCII
  599.             cf.WriteLine('DirectShowSource("'+ fToScan +'", fps='+ f.fRate.value +', convertfps=true)');
  600.  
  601.             if (extSubtitles)
  602.             {
  603.                 cf.WriteLine('LoadPlugin("'+ localPath +'\\Vobsub\\VSFilter.dll")');
  604.                 if (subIsText)
  605.                     cf.WriteLine('TextSub("'+ extSubtitles +'")');
  606.                 else
  607.                     cf.WriteLine('VobSub("'+ extSubtitles +'")');
  608.             }
  609.             cf.WriteLine('return last');
  610.             cf.close();
  611.         }
  612.          catch(e)
  613.          {
  614.              alert("Error creating AVS file: "+ e.message);
  615.             if (closeFSO) psfo=null;
  616.             cf=null;
  617.             return fToScan;
  618.          }
  619.         if (closeFSO) psfo=null;
  620.         cf=null;
  621.         return AVSfile;
  622.     }
  623.     // Use AVS for DVD titles after DGIndex is done
  624.     else if (isMultiVOB && window.indexComplete && f.lang && f.lang.value != "" && f.lang.value != "-1")
  625.     {
  626.         if (doReuse && window.AVSfile)
  627.         {
  628.             if (closeFSO) pfso=null;
  629.             return AVSfile;
  630.         }
  631.  
  632.         if (!window.secOutPath)
  633.             setSecondaryOutPath();
  634.  
  635.         try
  636.         {
  637.             // First, make sure we have a d2v file
  638.             if (!window.pfso)
  639.             {
  640.                 closeFSO=true;
  641.                 window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  642.             }
  643.             if (!pfso.FileExists( indexFile +".d2v" ))
  644.             {
  645.                 if (closeFSO) pfso=null;
  646.                 return fToScan;
  647.             }
  648.  
  649.             // Now, let's generate the AVS file
  650.             window.AVSfile = indexFile +".avs";
  651.             var cf = pfso.Opentextfile(AVSfile, 2, true, 0);  // Writing - Create if needed - ASCII
  652.             cf.WriteLine('LoadPlugin("'+ localPath +'\\DGMPGDec\\dgdecode.dll")');
  653.             cf.WriteLine('LoadPlugin("'+ localPath +'\\Vobsub\\VSFilter.dll")');
  654.             cf.WriteLine('video=mpeg2source("'+ indexFile +'.d2v")');
  655.             if (f.subt && (""+f.subt.value) != "" && window.vsCfg)
  656.                 cf.WriteLine('video=VobSub(video,"'+ vsCfg +'")');
  657.             getWavFileName();
  658.             cf.WriteLine('audio=WavSource("'+ wavFileName +'")');
  659.             cf.WriteLine('AudioDub(video, audio)');
  660.             cf.WriteLine('return last');
  661.             cf.close();
  662.         }
  663.          catch(e)
  664.          {
  665.              alert("Error creating AVS file for DVD. "+ e.message);
  666.             if (closeFSO) psfo=null;
  667.             cf=null;
  668.             return fToScan;
  669.          }
  670.         if (closeFSO) psfo=null;
  671.         cf=null;
  672.         return AVSfile;
  673.     }
  674.     else if (doReuse && window.AVSfile)
  675.     {
  676.         if (closeFSO) pfso=null;
  677.         return AVSfile;
  678.     }
  679.     else
  680.     {
  681.         if (closeFSO) pfso=null;
  682.         return fToScan;
  683.     }
  684. }
  685.  
  686. // Get a screenshot of the video for Cropping
  687. function getScreenShot(timeStamp, useSSAVS)
  688. {
  689.     if (timeStamp == 'IMPORT')
  690.     {
  691.         if (document.Player1 && document.Player1.controls)
  692.         {
  693.             timeStamp = document.Player1.controls.currentPosition;
  694.             shotPos = parseInt(timeStamp);
  695.         }
  696.         else
  697.             return;
  698.     }
  699.  
  700.     if (shotPos < 0) shotPos=0;
  701.     if (timeStamp < 0) timeStamp=0;
  702.     if (shotPos > inTarget) shotPos=inTarget;
  703.     if (timeStamp > inTarget) timeStamp=inTarget;
  704.  
  705.     var fName = fileInput;
  706.     if (!fName) return;
  707.  
  708.     if (shotPos > 0 && shotPos == lastShotPos) return;
  709.     lastShotPos = shotPos;
  710.  
  711.     var stTime = (timeStamp) ? timeStamp : 60;
  712.      var fileToScan = fName;
  713.      var cW = da.cropMovie.offsetWidth;
  714.      if (cW % 2 == 1) cW++;
  715.      var cH = da.cropMovie.offsetHeight;
  716.      if (cH % 2 == 1) cH++;
  717.      var resol = cW +'x'+ cH;
  718.  
  719.     var ssInputFile = fileToScan;//checkAVS(fileToScan, true);
  720.  
  721.     document.cropImage.src = "images/pixel.png";
  722.  
  723.     try
  724.     {
  725.         var multiCat = "";
  726.         if (isMultiVOB && useSSAVS)
  727.         {
  728.             // For VTS VOBS we can use an AVS with concatenated VOBs for the screenshot, giving us access to the whole DVD title
  729.             var m = ssInputFile.match(/^(.+)\\(vts_.*)$/i);
  730.             if (m)
  731.             {
  732.                 if (ssAVSfile)
  733.                     ssInputFile = ssAVSfile;
  734.                 else
  735.                 {
  736.                     var nParts = 1;
  737.                     window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  738.                     while(nParts < 10)
  739.                     {
  740.                         if (!pfso.FileExists( fName.replace(/_\d+\.vob$/i, "_"+ nParts +".vob") ))
  741.                         {
  742.                             nParts--;
  743.                             break;
  744.                         }
  745.                         if (multiCat) multiCat += "+";
  746.                         multiCat += 'DirectShowSource("'+ m[1] +'\\'+ m[2].replace(/_\d+\.vob$/i, "_"+ nParts +".vob") +'")';
  747.                         nParts++;
  748.                     }
  749.                     if (nParts < 1)
  750.                     {
  751.                         pfso=null;
  752.                         alert("Error: Unable to find all parts of the DVD VOBs");
  753.                         return;
  754.                     }
  755.                     ssAVSfile = ssInputFile = "ffshot.avs";
  756.                     var cf = pfso.Opentextfile(ssInputFile, 2, true, 0);  // Writing - Create if needed - ASCII
  757.                     cf.WriteLine(multiCat);
  758.                     cf.WriteLine('return last');
  759.                     cf.close();
  760.                     pfso=null;
  761.                 }
  762.             }
  763.         }
  764.  
  765.         window.encodeShell = new ActiveXObject( "WScript.shell" );
  766. //        encodeShell.run( '%comspec% /c .\\Engine\\MediaCellEngine.exe -s '+ resol +' -vframes 1 -i "'+ ssInputFile +'"-ss '+ stTime +' -bitexact -y .\\vmscreen.mjpeg > .\\mmshot 2 >&1', 0, true );
  767.         encodeShell.run( '%comspec% /c .\\Engine\\MediaCellEngine.exe -s '+ resol +' -vframes 1 -i "'+ ssInputFile +'" -ss '+ stTime +' -bitexact -y .\\vmscreen.mjpeg > .\\mmshot.log', 0, true );
  768.                 //for(i=0;i<1000000;i++);
  769.         window.outStream=null;
  770.         window.encodeShell = new ActiveXObject( "WScript.shell" );
  771.         encodeShell.run( '%comspec% /c move .\\vmscreen.mjpeg .\\vmscreen.jpg', 0, true );
  772.         window.outStream=null;
  773.         //alert('%comspec% /c .\\Engine\\MediaCellEngine.exe -s '+ resol +' -vframes 1 -i "'+ ssInputFile +'"-ss '+ stTime +' -bitexact -y .\\vmscreen.mjpeg  > .\\mmshot 2 >&1');
  774.      }
  775.      catch(e)
  776.      {
  777.          if (debugMode) alert("Error during screenshot capture. "+ e.message);
  778.          encodeShell=null;
  779.          pfso=null;
  780.          return;
  781.      }
  782.  
  783.     for(i=0;i<10000;i++);
  784.     encodeShell=null;
  785.  
  786.     // For multi-VOB, if we get an empty image, we need to get the screenshot from a Concatenated VOB instead
  787.     if (isMultiVOB && !useSSAVS)
  788.     {
  789.         try
  790.         {
  791.             window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  792.             var fvob = pfso.GetFile( ".\\vmscreen.jpg" );
  793.             if (fvob && parseInt(""+fvob.Size) < 10)
  794.             {
  795.                 fvob=null;
  796.                 pfso=null;
  797.                 lastShotPos=-1;
  798.                 getScreenShot(timeStamp, true);
  799.                 return;
  800.             }
  801.         }
  802.         catch(e) 
  803.         {
  804.             if (debugMode) alert("Error getting VOB screenshot. "+ e.message);
  805.         }
  806.         pfso=null;
  807.     }
  808.  
  809.      document.cropImage.src = ".\\vmscreen.jpg";
  810.      document.cropImage.width = da.cropMovie.offsetWidth - 2;
  811.     document.cropImage.height = da.cropMovie.offsetHeight - 2;
  812.  
  813.     oF.scPos.value = shotPos +" / "+ inTarget;
  814.  
  815.     // If we are now using an AVS script to read the video, but the original track info came from FFinfo
  816.     if (needTocheckAVStrack)
  817.     {
  818.         needTocheckAVStrack=false;
  819.         window.scanLog = String();
  820.         window.outStream = null;
  821.         setTimeout("readScanAVStrack(1)", 500);
  822.     }
  823. }
  824.  
  825. // Read the output from MediaCellEngine's screenshot log to determine the right mapping for Audio/Video from the AVS script
  826. function readScanAVStrack(isStart)
  827. {
  828.     if (!window.outStream)
  829.     {
  830.         window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  831.         window.outStream = pfso.OpenTextFile('.\\mmshot');
  832.     }
  833.     var m, line = String();
  834.     var atEnd = outStream.atEndOfStream;
  835.     var done = false;
  836.  
  837.     if (!atEnd)
  838.     {
  839.         line = outStream.Read(1000);
  840.         scanLog += line.replace(/[\r\n]/g,"|") +'|';
  841.  
  842.         if (line.search(/Start encoding.../) > 0)
  843.         {
  844.             done=true;
  845.         }
  846.         else
  847.         {
  848.             if (line.search(/A>/) >= 0)
  849.             {
  850.                 encodeShell=null;
  851.                 pfso=null;
  852.                 alert("Error:\n\n"+ line);
  853.                 line = "ERROR";
  854.                 return;
  855.             }
  856.         }
  857.     }
  858.  
  859.     if (!done && isStart < 20)
  860.     {
  861.         setTimeout("readScanAVStrack("+ (isStart+1) +")",300);
  862.         return;
  863.     }
  864.  
  865.     if (scanLog && scanLog.search(/Stream #0\..[^|:]*: Video/) < 0)
  866.     {
  867.         encodeShell=null;
  868.         pfso=null;
  869.         alert("Invalid Video File.");
  870.         return;
  871.     }
  872.     encodeShell=null;
  873.     outStream.close();
  874.     window.outStream=null;
  875.     pfso=null;
  876.  
  877.     var m = scanLog.match(/Stream #0\.(\d+)[^|:]*: Video:/);
  878.     if (m)
  879.         videoMap = m[1];
  880.  
  881.     m = scanLog.match(/Stream #0\.(\d+)[^|:]*: Audio:/);
  882.     if (m)
  883.         audioMap = m[1];
  884.  
  885.     checkedAVStrack = true;
  886. }
  887.  
  888. // Read the output from MediaInfo and when it is complete, send it to the parser
  889. function readScan(isStart)
  890. {
  891.     if (!window.outStream)
  892.     {
  893.         window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  894.         window.outStream = pfso.OpenTextFile('.\\minfo.log');
  895.     }
  896.     var m, line = String();
  897.     var atEnd = outStream.atEndOfStream;
  898.     var reStart = (isStart && atEnd);
  899.     while( !atEnd && (line = outStream.ReadLine()) )
  900.     {
  901.         scanLog += line +'|';
  902.         if (isStart && line.search(/General/) < 0)
  903.         {
  904.             encodeShell=null;
  905.             pfso=null;
  906.             if (line.search(/copy protect/i) > 0)
  907.                 alert("MediaCell cannot convert copy protected DVDs.");
  908.             else
  909.                 alert("Error:\n\n"+ line);
  910.             line = "ERROR";
  911.             ff.txtOut.value = "";
  912.             f.duration.value = "";
  913.             return;
  914.         }
  915.         isStart = false;
  916.         atEnd = outStream.atEndOfStream;
  917.     }
  918.  
  919.     if (scanLog && scanLog.search(/Video #0/) < 0)
  920.     {
  921.         encodeShell=null;
  922.         pfso=null;
  923.         alert("Invalid video file");
  924.         ff.txtOut.value = "";
  925.         f.duration.value = "";
  926.         return;
  927.     }
  928.  
  929.     if (scanLog && scanLog.search(/using MediaInfoLib/) >= 0)
  930.     {
  931.         // Create the default out path if necessary
  932.         try
  933.         {
  934.             if (!pfso.FolderExists(defaultOutPath))
  935.                 pfso.CreateFolder(defaultOutPath);
  936.         }
  937.         catch (e)
  938.         {
  939.             if (debugMode) alert("Unable to create out folder: "+ defaultOutPath +".\nError: "+ e.message)
  940.             m = fileInput.match(/^(.+)\\([^\\]+)$/);
  941.             defaultOutPath = ((m) ? m[1] : ".") + "\\";
  942.         }
  943.  
  944.         encodeShell=null;
  945.         pfso=null;
  946.         f.duration.value = "";
  947.         parseScan();
  948.     }
  949.     else if (reStart)
  950.         setTimeout("readScan(1)", 100);
  951.     else
  952.         setTimeout("readScan()", 100);
  953. }
  954.  
  955. // Read the output from MediaCellEngine's scan and when it is complete, send it to the parser
  956. function readScan2(isStart)
  957. {
  958.     if (!window.outStream)
  959.     {
  960.         window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  961.         window.outStream = pfso.OpenTextFile('.\\mediainfo.log');
  962.     }
  963.     var m, line = String();
  964.     var atEnd = outStream.atEndOfStream;
  965.     var done = false;
  966.  
  967.     if (!atEnd)
  968.     {
  969.         line = outStream.Read(1000);
  970.         scanLog += line.replace(/[\r\n]/g,"|") +'|';
  971.  
  972.         if (line.search(/Must supply at least/) > 0)
  973.         {
  974.             done=true;
  975.         }
  976.         else
  977.         {
  978.             if (line.search(/A>/) >= 0)
  979.             {
  980.                 encodeShell=null;
  981.                 pfso=null;
  982.                 alert("Error:\n\n"+ line);
  983.                 line = "ERROR";
  984.                 ff.txtOut.value = "";
  985.                 f.duration.value = "";
  986.                 return;
  987.             }
  988.         }
  989.     }
  990.  
  991.     if (!done && isStart < 20)
  992.     {
  993.         setTimeout("readScan2("+ (isStart+1) +")",300);
  994.         return;
  995.     }
  996.  
  997.     if (scanLog && scanLog.search(/Stream #0\..[^|:]*: Video/) < 0)
  998.     {
  999.         encodeShell=null;
  1000.         pfso=null;
  1001.         alert("Invalid Video File.");
  1002.         ff.txtOut.value = "";
  1003.         f.duration.value = "";
  1004.         return;
  1005.     }
  1006.  
  1007.     encodeShell=null;
  1008.     pfso=null;
  1009.     parseScan2();
  1010. }
  1011.  
  1012. // Parse the MediaInfo output for details on the video
  1013. function parseScan()
  1014. {
  1015.     var m, t;
  1016.  
  1017.     m = scanLog.match(/\|Complete name[\s\t]+: ([^|]+)\.([^|]+)\|/);
  1018.     oF.fName.value = (m) ? m[1] +'_M.'+ oF.format.value.toLowerCase() : '';
  1019.  
  1020.     if (m)
  1021.     {
  1022.         t = m[1].match(/^(.*)\\([^\\]+)$/);
  1023.         if (t)
  1024.             outTitle = t[2];
  1025.     }
  1026.  
  1027.     m = fileInput.match(/^(.+)\.([a-zA-Z0-9_]+)$/i);
  1028.     if (m)
  1029.         oF.fName.value = m[1] +'_M.'+ oF.format.value.toLowerCase();
  1030.  
  1031.     if (isMultiVOB || isSingleVOB)
  1032.     {
  1033.         // Rename output file (VTS_*) based on folder name instead
  1034.         m = fileInput.match(/^(.+)\\([^\\]+)\\vts_.+_([0-9]+)\..+$/i);
  1035.         if (m)
  1036.         {
  1037.             var leadPath = m[1];
  1038.             if (leadPath.search(/^[A-Za-z]:$/)==0)
  1039.             {
  1040.                 // This is probably a DVD drive, so let's try to use the Volume Name instead
  1041.                 try
  1042.                 {
  1043.                     var vfso = new ActiveXObject("Scripting.FileSystemObject");
  1044.                     var drive = vfso.GetDrive(vfso.GetDriveName(fileInput));
  1045.                     leadPath = drive.VolumeName;
  1046.                     outTitle = leadPath;
  1047.                     drive=null;
  1048.                     vfso=null;
  1049.                 }
  1050.                 catch(e) 
  1051.                 {
  1052.                     if (debugMode) alert("Getting volume name for DVD drive: "+ e.message);
  1053.                 }
  1054.             }
  1055.             oF.fName.value = leadPath +'\\'+ m[2] + '\\'+ m[2] + ((isSingleVOB) ? ('_'+ m[3]) : '') +'_M.'+ oF.format.value.toLowerCase();
  1056.         }
  1057.     }
  1058.  
  1059.     if (outPath == '.')
  1060.     {
  1061.         outTitle = cleanTitle(outTitle);
  1062.         outPath = defaultOutPath + outTitle;
  1063.         oF.fName.value = outPath +'\\'+ outTitle +'_M.'+ oF.format.value.toLowerCase();;
  1064.     }
  1065.  
  1066.     m = scanLog.match(/\|File size[^|]+\|File size[^|]+\|File size[^|]+\|File size[\s\t]+: ([^|]+)\|/);
  1067.     f.fSize.value = (m) ? m[1] : '';
  1068.  
  1069.     if (isMultiVOB)
  1070.     {
  1071.         f.duration.value = (dvdDuration) ? dvdDuration : "Multi-Part DVD";
  1072.         f.fSize.value = "Multi: "+ f.fSize.value;
  1073.         //ff.vFile.value = ff.vFile.value.replace(/_\d+\.vob$/i,"_1.vob");
  1074.     }
  1075.     else
  1076.     {
  1077.         m = scanLog.match(/\|PlayTime[\s\t]+: (\d+:\d+:[^|]+)\|/);
  1078.         if (m) f.duration.value = m[1];
  1079.  
  1080.         m = scanLog.match(/\|PlayTime[\s\t]+: ([^|]+)\|/);
  1081.         var tmpTarget = (m) ? (parseInt(m[1])/1000) : '1';
  1082.         if (!dvdDuration || tmpTarget > 1)
  1083.             inTarget = (m) ? (parseInt(m[1])/1000) : '1';
  1084.         else if (dvdDuration)
  1085.             f.duration.value = dvdDuration;
  1086.     }
  1087.  
  1088.     m = scanLog.match(/Video #0.+\|Codec[\s\t]+: ([^|]+)\|.+\|Frame rate/);
  1089.     f.vCodec.value = (m) ? m[1] : '';
  1090.  
  1091.     m = scanLog.match(/Audio #0.+\|Codec[\s\t]+: ([^|]+)\|/);
  1092.     f.aCodec.value = (m) ? m[1] : '';
  1093.  
  1094.     m = scanLog.match(/Video #0.+\|Bit rate[^|]+\|Bit rate[\s\t]+: ([^|]+)\|.+\|Frame rate/);
  1095.     f.vRate.value = (m) ? m[1] : '';
  1096.  
  1097.     m = scanLog.match(/Audio #0.+\|Bit rate[^|]+\|Bit rate[\s\t]+: ([^|]+)\|/);
  1098.     f.aRate.value = (m) ? m[1] : '';
  1099.  
  1100.     m = scanLog.match(/\|Frame rate[\s\t]+: ([^|]+)\|/);
  1101.     f.fRate.value = (m) ? m[1] : '';
  1102.  
  1103.     m = scanLog.match(/Audio #0.+\|Sampling rate[\s\t]+: ([^|]+Hz\s*)\|/);
  1104.     f.sampling.value = (m) ? m[1] : '';
  1105.  
  1106.     m = scanLog.match(/Audio #0.+\|Channels[\s\t]+: ([^|]+)\|/);
  1107.     f.channels.value = (m) ? m[1] : '';
  1108.  
  1109.     m = scanLog.match(/\|Aspect ratio[\s\t]+: ([^|]+)\|Aspect ratio[\s\t]+: ([^|]+)\|/);
  1110.     f.ratio.value = (m) ? (m[2] +" ("+ m[1] +")") : '';
  1111.     inRatio = (m) ? m[1] : '';
  1112.  
  1113.     if (!m)
  1114.     {
  1115.         m = scanLog.match(/\|Aspect ratio[\s\t]+: ([^|]+)\|/);
  1116.         f.ratio.value = (m) ? m[1] : '';
  1117.         inRatio = (m) ? m[1] : '';
  1118.     }
  1119.  
  1120.     m = scanLog.match(/\|Width[\s\t]+: ([^|]+)\|Height[\s\t]+: ([^|]+)\|/);
  1121.     f.resolution.value = (m) ? m[1] +'x'+ m[2] : '';
  1122.  
  1123.     if (m && !inRatio) inRatio = m[1]/m[2];
  1124.  
  1125.     // Use MediaCellEngine to get additional info
  1126.     scanFile2();
  1127.     return;
  1128. }
  1129.  
  1130. // Get the byte sizes of the VOB files for progress monitoring
  1131. function getVOBsizes()
  1132. {
  1133.     var closePFSO=false;
  1134.     var retVal = "-1";
  1135.     try
  1136.     {
  1137.         if (!window.pfso)
  1138.         {
  1139.             closePFSO=true;
  1140.             window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  1141.         }
  1142.         
  1143.         var nParts = 1;
  1144.         window.vobBytes = new Array();
  1145.         window.vobBytesTotal = 0;
  1146.         while(nParts < 10)
  1147.         {
  1148.             if (!pfso.FileExists( fileInput.replace(/_\d+\.vob$/i, "_"+ nParts +".vob") ))
  1149.             {
  1150.                 nParts--;
  1151.                 break;
  1152.             }
  1153.             var fvob = pfso.GetFile( fileInput.replace(/_\d+\.vob$/i, "_"+ nParts +".vob") );
  1154.             vobBytes[nParts-1] = fvob.Size;
  1155.             vobBytesTotal += vobBytes[nParts-1];
  1156.             nParts++;
  1157.             fvob = null;
  1158.         }
  1159.         if (vobBytesTotal > 1024 * 1024 * 1024)
  1160.             retVal = (Math.round(100 * (vobBytesTotal/1024/1024/1024)) / 100) + " GB";
  1161.         else if (vobBytesTotal > 1024 * 1024)
  1162.             retVal = (Math.round(100 * (vobBytesTotal/1024/1024)) / 100) + " MB";
  1163.         else if (vobBytesTotal > 1024)
  1164.             retVal = (Math.round(100 * (vobBytesTotal/1024)) / 100) + " KB";
  1165.         else
  1166.             retVal = vobBytesTotal + " bytes";
  1167.     }
  1168.     catch(e)
  1169.     {
  1170.         if (debugMode) alert("Getting VOB size. Error: "+ e.message);
  1171.         window.window.vobBytes=null;
  1172.         window.vobBytesTotal=null;
  1173.     }    
  1174.     if (closePFSO) pfso=null;
  1175.     return retVal;
  1176. }
  1177.  
  1178. // Parse the MediaCellEngine scan output for details on the video
  1179. function parseScan2()
  1180. {
  1181.     var m;
  1182.  
  1183.     if (ffInputFile.search(/\.avs$/i) < 0)
  1184.     {
  1185.         m = scanLog.match(/File Size: ([^|]+)\|/);
  1186.         f.fSize.value = (m) ? m[1] : (f.fSize.value) ? f.fSize.value :  '';
  1187.     }
  1188.  
  1189.     // Special processing of DVD VOBs
  1190.     if (isMultiVOB || isSingleVOB)
  1191.     {
  1192.         if (isMultiVOB)
  1193.         {
  1194.             f.duration.value = (dvdDuration) ? dvdDuration : "Multi-Part DVD";
  1195.             //if (f.fSize.value.search(/^Multi/) < 0)
  1196.                 //f.fSize.value = "Multi: "+ f.fSize.value;
  1197.             f.fSize.value = getVOBsizes();
  1198.             if (f.fSize.value == "-1")
  1199.                 f.fSize.value = "Multi: "+ f.fSize.value;
  1200.  
  1201.             //ff.vFile.value = ff.vFile.value.replace(/_\d+\.vob$/i,"_1.vob");
  1202.         }
  1203.         else
  1204.         {
  1205.             m = scanLog.match(/Duration: (\d+):(\d+):([^,]+),/);
  1206.             if (m)
  1207.             {
  1208.                 f.duration.value = m[1]+":"+m[2]+":"+m[3];
  1209.                 var tmpTarget = 60*60*parseInt(m[1])+60*parseInt(m[2])+ parseInt(m[3]);
  1210.                 if (tmpTarget > (60*60*50) && dvdDuration)
  1211.                     f.duration.value = dvdDuration;
  1212.                 else
  1213.                     inTarget = tmpTarget;
  1214.             }
  1215.         }
  1216.  
  1217.         // Check that the Audio Languages correspond to the Audio streams in the VOB
  1218.         streams = new Array();
  1219.         nStreams=0;
  1220.         for(i=0; i < 10; i++)
  1221.         {
  1222.             var re = new RegExp("Stream #0\."+ (i+1) +"[^|:]*: Audio:");
  1223.             if (scanLog.search(re) < 0)
  1224.                 break;
  1225.  
  1226.             re = new RegExp("Stream #0\."+ (i+1) +"[^|:]*: Audio:[^:]+5:1");
  1227.             if (scanLog.search(re) >= 0)
  1228.                 streams[i] = "6ch";
  1229.             else
  1230.                 streams[i] = "2ch";
  1231.             nStreams++;
  1232.         }
  1233.  
  1234.  
  1235.         // Display the Language options
  1236.         if (langArray && langArray.length > 0)
  1237.         {
  1238.             // Remove any previous options
  1239.             for(i=f.lang.options.length; i >= 0; i--)
  1240.                 f.lang.options[i] = null;
  1241.  
  1242.             // TODO: Support DVD with no audio
  1243.             //f.lang.options[f.lang.options.length] = new Option("- Select One -","-1");
  1244.  
  1245.             // If there are less streams, let's filter out the missing ones based on their channels
  1246.             if (nStreams < langArray.length)
  1247.             {
  1248.                 nStreams = 0;
  1249.                 for(i=0; i < langArray.length; i++)
  1250.                 {
  1251.                     if (langArray[i].search(streams[nStreams]) > 0)
  1252.                     {
  1253.                         // Since there are less streams than DVD languages, we can't be sure which languages are left
  1254.                         // So se display "Audio" to be generic
  1255.                         f.lang.options[f.lang.options.length] = new Option("Audio #"+ (nStreams+1) +" "+ streams[nStreams], nStreams+1);
  1256.                         nStreams++;
  1257.                     }
  1258.                     if (nStreams >= streams.length)
  1259.                         break;
  1260.                 }
  1261.             }
  1262.             else
  1263.                 for(i=0; i < langArray.length; i++)
  1264.                     f.lang.options[i] = new Option(langArray[i], i+1);
  1265.  
  1266.             document.getElementById("langLbl").style.visibility = "visible";
  1267.             f.lang.style.visibility = "visible";
  1268.             ssSyncOptions(f.lang);
  1269.         }
  1270.  
  1271.         // Display the Subtitle options
  1272.         if (subArray && subArray.length > 0)
  1273.         {
  1274.             // Remove any previous options
  1275.             for(i=f.subt.options.length; i >= 0; i--)
  1276.                 f.subt.options[i] = null;
  1277.  
  1278.             f.subt.options[f.subt.options.length] = new Option("None","");
  1279.             for(var si=0; si < subArray.length; si++)
  1280.                 f.subt.options[si+1] = new Option(langCodeToStr(subArray[si]), subArray[si]);
  1281.  
  1282.             document.getElementById("subtLbl").style.visibility = "visible";
  1283.             f.subt.style.visibility = "visible";
  1284.             ssSyncOptions(f.subt);
  1285.         }
  1286.     }
  1287.     else if (isSingle2ndPass && dvdDuration)
  1288.     {
  1289.         // inTarget is already ok
  1290.     }
  1291.     else
  1292.     {
  1293.         m = scanLog.match(/Duration: (\d+):(\d+):([^,]+),/);
  1294.         if (m)
  1295.         {
  1296.             f.duration.value = m[1]+":"+m[2]+":"+m[3];
  1297.             inTarget = 60*60*parseInt(m[1])+60*parseInt(m[2])+ parseInt(m[3]);
  1298.         }
  1299.     }
  1300.  
  1301.     // Force a focus on the Device Select
  1302.     setTimeout("ssSyncOptions(oF.device)", 200);
  1303.  
  1304.     m = scanLog.match(/Duration: [^|]+bitrate: ([^|]+)\|/);
  1305.     if (m && m[1] != "N/A") f.vRate.value = m[1];
  1306.  
  1307.     m = scanLog.match(/Stream #0\.(\d+)[^|:]*: Video: (.+),\s+(\d+x\d+),\s+([^,]+) fps,[^|]+\|/);
  1308.     if (m)
  1309.     {
  1310.         videoMap = m[1];
  1311.         if (f.vCodec.value=="") f.vCodec.value = m[2];
  1312.         f.resolution.value = m[3];
  1313.         var fps = m[4];
  1314.         if (fps && parseInt(fps) > 100)
  1315.         {
  1316.             // Error in Frame Rate. Check if there's compensation somewhere
  1317.             m = scanLog.match(/Seems that.+\((\d+)\/1\) ->\s+([0-9.]+)\s+\(\d+\/1\)/);
  1318.             if (m && parseInt(m[1]) == fps)
  1319.                 f.fRate.value = m[2];
  1320.             else
  1321.                 f.fRate.value = (f.fRate.value) ? f.fRate.value : '30.00';
  1322.         }
  1323.         else
  1324.             f.fRate.value = fps;
  1325.  
  1326.         if (parseInt(1*inRatio) > 5)
  1327.         {
  1328.             var iWidth = parseInt(f.resolution.value.substr(0,f.resolution.value.search('x')));
  1329.             var iHeight= parseInt(f.resolution.value.substr(f.resolution.value.search('x')+1));
  1330.  
  1331.             inRatio = iWidth/iHeight;
  1332.             f.ratio.value = inRatio;
  1333.         }
  1334.     }
  1335.  
  1336.     m = scanLog.match(/Input #0,\s+([^|,]+),/);
  1337.     inputFormat = (m) ? m[1] : '';
  1338.  
  1339.     m = scanLog.match(/Stream #0\.(\d+)[^|:]*: Audio: ([^,]+),\s+([^,]+),\s+([^,]+),\s+([^|]+)\|/);
  1340.     if (m)
  1341.     {
  1342.         audioMap = m[1];
  1343.         f.aCodec.value = m[2];
  1344.         f.sampling.value = m[3];
  1345.         f.channels.value = m[4];
  1346.         f.aRate.value = m[5];
  1347.     }
  1348.  
  1349. //    m = scanLog.match(/\|Aspect ratio[\s\t]+: ([^|]+)\|Aspect ratio[\s\t]+: ([^|]+)\|/);
  1350. //    f.ratio.value = (m) ? (m[2] +" ("+ m[1] +")") : '';
  1351. //    inRatio = (m) ? m[1] : '';
  1352.  
  1353.     if (isSingleVOB && !isSingle2ndPass)
  1354.     {
  1355.         // Now parse the actual file instead of the first VOB for more details
  1356.         isSingleVOB = false;
  1357.         isSingle2ndPass = true;
  1358.         scanFile2();
  1359.         return;
  1360.     }
  1361.     else if (isSingle2ndPass)
  1362.     {
  1363.         isSingleVOB = true;
  1364.         isSingle2ndPass = false;
  1365.     }
  1366.  
  1367.     optimize();
  1368.  
  1369.     resetForm(oF, "on");
  1370.  
  1371.     // For TiVo files, force a start at 5 seconds to offset audio/sync issues
  1372.     if (fileInput.search(/\.tivo$/i) > 0 && oF.recStart)
  1373.         oF.recStart.value = 5;
  1374.     else
  1375.         oF.recStart.value = 0;
  1376.  
  1377.     oF.recEnd.value = inTarget;
  1378.     recDuration = inTarget;
  1379.  
  1380.     if (parseInt(oF.vRate.value) > 0) estimateSize();
  1381.  
  1382.     if (document.Player1 && fF.usePreview.checked)
  1383.         playerLoad(document.Player1, (window.fileInput) ? fileInput : "");
  1384. }
  1385.  
  1386. // Create the secondary files folder
  1387. function setSecondaryOutPath()
  1388. {
  1389.     var closeFSO = false;
  1390.     window.secOutPath = defaultOutPath + outTitle;
  1391.     try
  1392.     {
  1393.         window.secOutPath = defaultOutPath + outTitle +".vm";
  1394.         if (!window.pfso)
  1395.         {
  1396.             closeFSO = true;
  1397.             window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  1398.         }
  1399.         if (!pfso.FolderExists(secOutPath))
  1400.             pfso.CreateFolder(secOutPath);
  1401.     }
  1402.     catch (e)
  1403.     {
  1404.         if (debugMode) alert("Unable to create secondary output path. "+ e.message);
  1405.         // If we can't create it, we just take the regular out path
  1406.         window.secOutPath = defaultOutPath + outTitle;
  1407.     }
  1408.     if (closeFSO) pfso = null;
  1409. }
  1410.  
  1411. // Uses DGIndex to prepare the DVD
  1412. function indexDVD(batchAction)
  1413. {
  1414.     // First, check if we need to extract subtitles
  1415.     if (f.subt && f.subt.value != "" && !window.vsCfg)
  1416.     {
  1417.         grabSubtitles(batchAction);
  1418.         if (!batchAction) return;  // When complete, grabSubtitles will call indexDVD() again
  1419.     }
  1420.  
  1421.     window.AVSfile=null;
  1422.     window.duringIndex = true;
  1423.     try
  1424.     {
  1425.         window.indexFile = oF.fName.value.replace(/\.[^.]+$/,"");
  1426.         var audioTrack = (f.lang && parseInt(1*f.lang.value) > 0) ? f.lang.value : audioMap;
  1427.  
  1428.         if (!window.secOutPath)
  1429.             setSecondaryOutPath();
  1430.  
  1431.         var m = oF.fName.value.match(/\\([^.\\]+)\.[^.]+$/);
  1432.         if (m)
  1433.             indexFile = secOutPath +"\\"+ m[1] +"_"+ audioTrack;
  1434.  
  1435.         // Don't repeat indexing if we already did it for this movie and audio track
  1436.         window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  1437.         if (pfso.FileExists( indexFile +".d2v" ) && !window.indexAborted)
  1438.         {
  1439.             pfso=null;
  1440.             ff.txtOut.value = "";
  1441.             window.duringIndex = false;
  1442.             if (window.nextDone == "INDEX")
  1443.             {
  1444.                 encodeAll("INDEX");  // Return to where we were in the Batch encoding
  1445.                 return;
  1446.             }
  1447.             //ff.txtOut.value = "Ready.";
  1448.             indexComplete = true;
  1449.             encode(null,null,true);  // Need to call this since we were trying to encode to begin with
  1450.             return;
  1451.         }
  1452.         pfso=null;
  1453.         window.indexAborted=null;
  1454.  
  1455.         // Start Indexing
  1456.         window.lastIndexCmd = '%comspec% /c .\\DGMPGDec\\DGIndex.exe -AIF=['+ fileInput +']'
  1457.             +' -OF=['+ indexFile +'] -TN='+ audioTrack +' -OM=3 -HIDE -EXIT';
  1458.         
  1459.         if (batchAction == "ADD")
  1460.             return;
  1461.  
  1462.         ff.txtOut.value = "Preparing DVD Title...";
  1463.         window.indexShell = new ActiveXObject( "WScript.shell" );
  1464.         indexShell.run(lastIndexCmd , 0, false );
  1465.         window.outStream=null;
  1466.      }
  1467.      catch(e)
  1468.      {
  1469.         window.indexShell = null;
  1470.          alert("DVD Indexing Error: "+ e.message);
  1471.          return;
  1472.      }
  1473.  
  1474.     // Start tracking progress on the indexing
  1475.     oF.encodeBtn.disabled = true;
  1476.     oF.encodeBtn.className = "goOff";
  1477.     oF.abortBtn.className = "abortOn";
  1478.     oF.encodeBtn.src="images/start_on.jpg";    
  1479.     oF.batchBtn.disabled = true;
  1480.     oF.batchBtn.className = "goOff";
  1481.     window.lastIPos=null;
  1482.  
  1483.     setTimeout("indexProgress(1)", 1000);
  1484. }
  1485.  
  1486. // Track progress of the indexing
  1487. function indexProgress(isStart)
  1488. {
  1489.     var hasAborted = (ff.txtOut.value.search(/DVD Preparation Aborted/i) == 0);
  1490.  
  1491.     if (!window.outStream)
  1492.     {
  1493.         window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  1494.         
  1495.         if (!pfso.FileExists(indexFile +".d2v"))
  1496.         {
  1497.             pfso=null;
  1498.             setTimeout("indexProgress(1)", 500);
  1499.             return;
  1500.         }
  1501.         window.outStream = pfso.OpenTextFile(indexFile +".d2v");
  1502.     }
  1503.     var m, pos, line = String();
  1504.     var atEnd = outStream.atEndOfStream;
  1505.     if( !atEnd && (line = outStream.Read(4000)) )
  1506.     {
  1507.         if (isStart && line.search(/DGIndexProject/) < 0)
  1508.         {
  1509.             if (isStart > 5)
  1510.             {
  1511.                 alert("Error:\n\n"+ line);
  1512.                 oF.encodeBtn.disabled = false;
  1513.                 oF.encodeBtn.className = "goOn";
  1514.                 oF.batchBtn.disabled = false;
  1515.                 oF.batchBtn.className = "batchOn";
  1516.                 oF.abortBtn.blur();
  1517.                 oF.encodeBtn.src="images/start_on.jpg";                
  1518.                 oF.abortBtn.className = "abortOff";
  1519.                 ff.txtOut.value = 'DVD Preparation Aborted.';
  1520.                 return;
  1521.             }
  1522.  
  1523.             // Give it a second and try again
  1524.             setTimeout("indexProgress("+ (isStart+1) +")", 1000);
  1525.         }
  1526.  
  1527.         line = line.replace(/[\r\n]/g,"@");
  1528.  
  1529.         m = line.match(/@[^\s]+\s[^\s]+\s(\d)+\s(\d+)[^@]+@*$/);
  1530.         if (m && parseInt(m[2]) > 0)
  1531.         {
  1532.             var currPart = parseInt(m[1]);
  1533.             var bytesDone = parseInt(m[2]);
  1534.             for(i=0; i < currPart; i++)
  1535.                 bytesDone += vobBytes[i];
  1536.  
  1537.             pos = bytesDone / vobBytesTotal * 100;
  1538.             if (pos > 100) pos = 100;
  1539.             if (pos < 1) pos = 1;
  1540.             if (window.lastIPos && pos < lastIPos) pos = lastIPos;
  1541.  
  1542.             if (!hasAborted)
  1543.                 ff.txtOut.value = "Preparing DVD Title ... " + Math.round(pos) +"%";
  1544.  
  1545.             da.progBar.style.width = Math.round(pos) +"%";
  1546.  
  1547.             if (startTm)
  1548.             {
  1549.                 encTimer = new Date();
  1550.                 var elapsed = (encTimer.getTime() - startTm);
  1551.                 var remains = Math.round(elapsed * 100 / pos) - elapsed;
  1552.                 var showSec = ((remains/60000) < 10); // Show seconds only when 10 minutes or less remain
  1553.  
  1554.                 if ((elapsed - lastElapsed) > 500)
  1555.                 {
  1556.                     lastElapsed = elapsed;
  1557.                     var elF = formatZero(Math.floor(remains / 3600000),2); // 1000ms * 60sec * 60min
  1558.                     remains -= Math.floor(remains / 3600000) * 3600000;
  1559.                     elF += ":"+ formatZero(Math.floor(remains / 60000),2);  // 1000ms * 60sec
  1560.                     remains -= Math.floor(remains / 60000) * 60000;
  1561.                     if (showSec)
  1562.                         elF += ":"+ formatZero(Math.floor(remains / 1000),2);
  1563.                     else
  1564.                         elF += ":00";
  1565.                     ff.recTime.value = elF;
  1566.                     encTimer = null;
  1567.                 }
  1568.             }
  1569.             m=null;
  1570.             window.lastIPos = pos;
  1571.         }
  1572.     }
  1573.  
  1574.     if (isStart)
  1575.     {
  1576.         ff.txtOut.value = "Preparing DVD Title ...";
  1577.         da.progCanvas.style.visibility = "visible";
  1578.         da.progBar.style.width = "0%";
  1579.         da.progBar.style.backgroundColor = "#FFA000";
  1580.         encTimer = new Date();
  1581.         startTm = encTimer.getTime();
  1582.         encTimer = null;
  1583.         lastElapsed = 0;
  1584.     }
  1585.  
  1586.     if (line && (line.search(/FINISHED/) >= 0 || line=="ERROR" || hasAborted))
  1587.     {
  1588.         if (!hasAborted)
  1589.         {
  1590.             oF.encodeBtn.disabled = false;
  1591.             oF.encodeBtn.className = "goOn";
  1592.             oF.batchBtn.disabled = false;
  1593.             oF.batchBtn.className = "batchOn";
  1594.             oF.abortBtn.className = "abortOff";
  1595.             oF.encodeBtn.src="images/start_1.jpg";
  1596.         }
  1597.         indexShell=null;
  1598.         pfso=null;
  1599.  
  1600.         if (line != 'ERROR')
  1601.         {
  1602.             da.progCanvas.style.visibility = "hidden";
  1603.             ff.recTime.value = "";
  1604.             startTm=null;
  1605.             window.duringIndex = false;
  1606.             if (!hasAborted && window.nextDone == "INDEX")
  1607.             {
  1608.                 encodeAll("INDEX");  // Return to where we were in the Batch encoding
  1609.                 return;
  1610.             }
  1611.             if (!hasAborted)
  1612.             {
  1613.                 //ff.txtOut.value = "Ready.";
  1614.                 indexComplete = true;
  1615.                 encode(null,null,true);  // Need to call this since we were trying to encode to begin with
  1616.             }
  1617.         }
  1618.         else
  1619.         {
  1620.             ff.txtOut.value = "Indexing Error.";
  1621.             da.progCanvas.style.visibility = "hidden";
  1622.             ff.recTime.value = "";
  1623.             startTm=null;
  1624.             window.duringIndex = false;
  1625.         }
  1626.         window.nextDone=null;
  1627.     }
  1628.     else
  1629.         setTimeout("indexProgress()", 500);
  1630. }
  1631.  
  1632. function resetForm(frm, action)
  1633. {
  1634.     for(var i=0; i < frm.length; i++)
  1635.     {
  1636.         if (action == "on" && frm[i].disabled)
  1637.         {
  1638.             frm[i].disabled = false;
  1639.             frm[i].style.backgroundColor = "white";
  1640.         }
  1641.         else if (action == "off" && !frm[i].disabled)
  1642.         {
  1643.             frm[i].disabled = true;
  1644.             frm[i].style.backgroundColor = "#EEEEEE";
  1645.         }
  1646.     }
  1647. }
  1648.  
  1649. function getPspName(nameAfterThis)
  1650. {
  1651.     var d = new Date(), idx=1000, stamp;
  1652.  
  1653.     // If an existing name is passed, get the next sequential number
  1654.     if (nameAfterThis)
  1655.     {
  1656.         var mm = nameAfterThis.match(/M4V2(\d+)\.MP4$/i);
  1657.         if (mm)
  1658.                 stamp = "M4V2"+ formatZero(parseInt(mm[1]) + 1, 4) +".MP4";
  1659.         else
  1660.                 stamp = "M4V2"+ (idx++) +".MP4";
  1661.     }
  1662.     else
  1663.     {
  1664.         // Try using a time stamp
  1665.         var tst = ""+ preZero(d.getHours()) + preZero(d.getMinutes());
  1666.         if (lastTStamp == tst)
  1667.         {
  1668.             rpt = (window.repeatStamp) ? window.repeatStamp : 1;
  1669.             tst = ""+ formatZero(parseInt(tst) - rpt, 4);
  1670.             window.repeatStamp = rpt+1;
  1671.         }
  1672.         else
  1673.             lastTStamp = tst;
  1674.  
  1675.         stamp = "M4V2"+ tst + ".MP4";
  1676.     }
  1677.  
  1678.     // If the file already exists, try a new naming convention
  1679.     window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  1680.     while(pfso.FileExists(outPath +'\\'+ stamp))
  1681.     {
  1682.         stamp = "M4V2"+ (idx++) +".MP4";
  1683.     }
  1684.     pfso=null;
  1685.  
  1686.     return stamp;
  1687. }
  1688.  
  1689. // Reset the settings to the installation defaults
  1690. function resetDefaultSettings()
  1691. {
  1692.     var answer = askYesNo("This will remove all the saved settings\nand revert to the installation defaults.\n\nAre you sure?");
  1693.     if (answer != 6) // If not Yes
  1694.                     return;
  1695.  
  1696.     var fcfo = new ActiveXObject( "Scripting.Filesystemobject" );
  1697.     try
  1698.     {
  1699.         fcfo.CopyFile("defaultConfig.xml", "config.xml", true);
  1700.     }
  1701.     catch(e)
  1702.     {
  1703.         alert("Unable to reset settings. Error: "+ e.message);
  1704.     }
  1705.     fcfo=null;
  1706. }
  1707.  
  1708. function getConfig(pass2)
  1709. {
  1710.     // When running a new version for the first time, grab the new devices from the default config XML, then merge-in the saved configs
  1711.     var getDefaultConfig = (!pass2 && lastVMRun != (''+VMHta.version));
  1712.     var cfFile = (getDefaultConfig) ? "defaultConfig.xml" : "config.xml";
  1713.  
  1714.     if (!pass2) window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  1715.     var cf = pfso.Opentextfile(cfFile);
  1716.     var line, m,found;
  1717.     if (!cf || cf.atEndOfStream)
  1718.     {
  1719.         alert('Missing "'+ cfFile +'" file');
  1720.         psfo=null;
  1721.         return;
  1722.     }
  1723.  
  1724.     if (!pass2) devices = new Array();
  1725.     var i = -1, j = -1, k = -1;
  1726.     while( !cf.atEndOfStream )
  1727.     {
  1728.         line = cf.ReadLine();
  1729.         m = line.match(/<DEVICE\s+name="(.+)"\s+label="(.+)">/);
  1730.         if (m)
  1731.         {
  1732.             i++;
  1733.             j=-1;
  1734.             if (i >= devices.length) devices[i] = new Object();
  1735.  
  1736.             // When merging the user's own config.xml, make sure we match up the devices from the defaultConfig
  1737.             if (pass2)
  1738.             {
  1739.                 for (var oi=0; oi < devices.length; oi++)
  1740.                     if (devices[oi].name == m[1])
  1741.                     {
  1742.                         i = oi;
  1743.                         break;
  1744.                     }
  1745.             }
  1746.  
  1747.             devices[i].name = m[1];
  1748.             devices[i].label = m[2];
  1749.             continue;
  1750.         }
  1751.  
  1752.         if (i >= 0)
  1753.         {
  1754.             m = line.match(/<img\s+src="(.+)".*\/>/);
  1755.             if (m)
  1756.                 devices[i].imageSrc = m[1];
  1757.  
  1758.             if (line.search(/<(screen|encodeSettings)/) >= 0)
  1759.             {
  1760.                 found = line.search(/\/>/) >= 0;
  1761.                 while(!cf.atEndOfStream && !found)
  1762.                 {
  1763.                     line += cf.ReadLine();
  1764.                     found = line.search(/\/>/) >= 0;
  1765.                 }
  1766.                 if (found)
  1767.                 {
  1768.                     m = line.match(/<(screen|encodeSettings)(.+)\/>/);
  1769.                     if (m)
  1770.                     {
  1771.                         line = "1"+ m[2].replace(/\s+$/,"").replace(/[\r\n]/g," ").replace(/\s\s/g," ").replace(/\s/g,";devices[i].");
  1772.                         eval(line);
  1773.                     }
  1774.                 }
  1775.             }
  1776.             m = line.match(/<ratio\s+min="([0-9.]+)">/);
  1777.             if (m)
  1778.             {
  1779.                 if (j < 0 && !pass2)
  1780.                     devices[i].crop = new Array();
  1781.  
  1782.                 j++;
  1783.                 k=-1;
  1784.                 if (j >= devices[i].crop.length)
  1785.                     devices[i].crop[j] = new Object();
  1786.                 devices[i].crop[j].min = parseFloat(m[1]);
  1787.             }
  1788.             if (j >= 0)
  1789.             {
  1790.                 if (line.search(/<preset/) >= 0)
  1791.                 {
  1792.                     if (!devices[i].crop[j].preset)
  1793.                         devices[i].crop[j].preset = new Array();
  1794.  
  1795.                     found = line.search(/\/>/) >= 0;
  1796.                     while(!cf.atEndOfStream && !found)
  1797.                     {
  1798.                         line += cf.ReadLine();
  1799.                         found = line.search(/\/>/) >= 0;
  1800.                     }
  1801.                     if (found)
  1802.                     {
  1803.                         k++;
  1804.                         if (k >= devices[i].crop[j].preset.length)
  1805.                             devices[i].crop[j].preset[k] = new Object();
  1806.                         m = line.match(/<preset(.+)\/>/);
  1807.                         if (m)
  1808.                         {
  1809.                             line = "1"+ m[1].replace(/\s+$/,"").replace(/[\r\n]/g," ").replace(/\s\s/g," ").replace(/\s/g,";devices[i].crop[j].preset[k].");
  1810.                             eval(line);
  1811.                         }
  1812.                     }
  1813.                 }
  1814.             }
  1815.         }
  1816.     }
  1817.     cf.close();
  1818.     if (getDefaultConfig)
  1819.         getConfig(true);
  1820.     else
  1821.     {
  1822.         psfo=null;
  1823.         if (pass2) saveConfig(true);    // Save the new config after merging the default and saved configs
  1824.     }
  1825. }
  1826.  
  1827. // Update the device settings for the current device
  1828. function updateDeviceSettings(newPreset)
  1829. {
  1830.     var i,j,k,d;
  1831.     if (!devices) getConfig(); // Retrieve the device configs
  1832.     d = devices[currDevice];
  1833.  
  1834.     d.format = oF.format.value;
  1835.     d.videoCodec = oF.vCodec.value;
  1836.     d.videoBitRate = oF.vRate.value;
  1837.     d.audioCodec = oF.aCodec.value;
  1838.     d.audioChannels = (oF.channels[1].checked) ? "1" : "2";
  1839.     d.audioSampling = oF.sampling.value;
  1840.     d.audioBitRate = oF.aRate.value;
  1841.     d.audioVolume = oF.volume.value;
  1842.  
  1843.     // Don't update the frameRate setting if it wasn't changed (to preserve HALF when it is overwritten by the minimum)
  1844.     if (oF.fRate.value != oF.fRate.lastValue)
  1845.     {
  1846.         if (parseFloat(f.fRate.value) - parseFloat(oF.fRate.value) < 0.2)
  1847.             d.frameRate = "FULL";
  1848.         else if ((f.fRate.value / 2) - parseFloat(oF.fRate.value) < 0.2)
  1849.             d.frameRate = "HALF";
  1850.         else if ((f.fRate.value / 3) - parseFloat(oF.fRate.value) < 0.2)
  1851.             d.frameRate = "THIRD";
  1852.         else
  1853.             d.frameRate = oF.fRate.value;
  1854.     }
  1855.  
  1856.     d.pixelWidth = oF.devRes.value.substr(0,oF.devRes.value.search('x'));
  1857.     d.pixelHeight= oF.devRes.value.substr(oF.devRes.value.search('x')+1);
  1858.  
  1859.     k = (newPreset) ? d.crop[currDevCrop].preset.length : currDevPres;
  1860.     if (newPreset)
  1861.         d.crop[currDevCrop].preset[k] = new Object();
  1862.  
  1863.     d.crop[currDevCrop].preset[k].resolution = oF.resolutionW.value +'x'+ oF.resolutionH.value;
  1864.     d.crop[currDevCrop].preset[k].cropLeft = oF.cropLeft.value;
  1865.     d.crop[currDevCrop].preset[k].cropRight = oF.cropRight.value;
  1866.     d.crop[currDevCrop].preset[k].cropTop = oF.cropTop.value;
  1867.     d.crop[currDevCrop].preset[k].cropBottom = oF.cropBottom.value;
  1868.     d.crop[currDevCrop].preset[k].lockRatio = (oF.lockRatio.checked) ? "YES" : "NO";
  1869. }
  1870.  
  1871. function saveConfig(silent)
  1872. {
  1873.     var cmess,newPreset;
  1874.     if (!silent)
  1875.     {
  1876.         if (!devices) getConfig(); // Retrieve the device configs
  1877.  
  1878.         if (!devices[currDevice].crop[currDevCrop]) 
  1879.         {
  1880.             devices=null;
  1881.             return;
  1882.         }
  1883.         
  1884.         cmess = "Do you want to save these settings for the "+ devices[currDevice].label +" ?";
  1885.     
  1886.         // If the resolution/crop settings have changed, we will add a new preset
  1887.         var currCrops = devices[currDevice].crop[currDevCrop].preset[currDevPres];
  1888.         newPreset = ((oF.resolutionW.value +'x'+ oF.resolutionH.value) != currCrops.resolution
  1889.                         || oF.cropLeft.value != currCrops.cropLeft
  1890.                         || oF.cropRight.value != currCrops.cropRight
  1891.                         || oF.cropTop.value != currCrops.cropTop
  1892.                         || oF.cropBottom.value != currCrops.cropBottom);
  1893.  
  1894.         if (newPreset) cmess += "\n\nThis will save a new preset given the updated resolution / crop settings.";
  1895.     }
  1896.  
  1897.     if (silent || confirm(cmess))
  1898.     {
  1899.         try
  1900.         {
  1901.             if (!silent) updateDeviceSettings(newPreset);
  1902.  
  1903.             window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  1904.             pfso.CopyFile("config.xml", "config_bak.xml", true);
  1905.             var cf = pfso.Opentextfile("config.xml", 2, true, 0);  // Writing - Create if needed - ASCII
  1906.             cf.WriteLine("<!--\r\n**\r\n**    MediaCell Configuration File\r\n**\r\n**    Copyright ⌐ 2006, MediaCell.\r\n**\r\n-->\r\n");
  1907.  
  1908.             var i,j,k,indent;
  1909.             for (i=0; i < devices.length; i++)
  1910.             {
  1911.                 cf.WriteLine('<DEVICE name="'+ devices[i].name +'" label="'+ devices[i].label +'">');
  1912.                 indent='    ';
  1913.                 cf.WriteLine(indent +'<img src="'+ devices[i].imageSrc +'" />');
  1914.                 cf.WriteLine(indent +'<screen pixelWidth="'+ devices[i].pixelWidth +'" pixelHeight="'+ devices[i].pixelHeight
  1915.                                     +'" cropWidth="'+ devices[i].cropWidth +'" cropHeight="'+ devices[i].cropHeight
  1916.                                     +'" positionLeft="'+ devices[i].positionLeft +'" positionTop="'+ devices[i].positionTop +'" />');
  1917.  
  1918.                 cf.WriteLine(indent +'<encodeSettings');
  1919.                 indent+='    ';
  1920.                 cf.WriteLine(indent +'format="'+ devices[i].format +'"\r\n'
  1921.                     + indent +'videoCodec="'+ devices[i].videoCodec +'"\r\n'
  1922.                     + indent +'videoBitRate="'+ devices[i].videoBitRate +'"\r\n'
  1923.                     + indent +'audioCodec="'+ devices[i].audioCodec +'"\r\n'
  1924.                     + indent +'audioSampling="'+ devices[i].audioSampling +'"\r\n'
  1925.                     + indent +'audioBitRate="'+ devices[i].audioBitRate +'"\r\n'
  1926.                     + indent +'audioChannels="'+ devices[i].audioChannels +'"\r\n'
  1927.                     + indent +'audioVolume="'+ devices[i].audioVolume +'"\r\n'
  1928.                     + indent +'frameRate="'+ devices[i].frameRate +'" />');
  1929.  
  1930.                 indent='    ';
  1931.                 cf.WriteLine(indent +'<crop>');
  1932.                 indent+='    ';
  1933.  
  1934.                 for(j=0; j < devices[i].crop.length; j++)
  1935.                 {
  1936.                     cf.WriteLine(indent +'<ratio min="'+ devices[i].crop[j].min +'">');
  1937.                     indent+='    ';
  1938.  
  1939.                     for(k=0; k < devices[i].crop[j].preset.length; k++)
  1940.                     {
  1941.                         cf.WriteLine(indent +'<preset id="'+ k
  1942.                             +'" resolution="'+ devices[i].crop[j].preset[k].resolution
  1943.                             +'" cropLeft="'+ devices[i].crop[j].preset[k].cropLeft
  1944.                             +'" cropRight="'+ devices[i].crop[j].preset[k].cropRight
  1945.                             +'" cropTop="'+ devices[i].crop[j].preset[k].cropTop
  1946.                             +'" cropBottom="'+ devices[i].crop[j].preset[k].cropBottom
  1947.                             +'" lockRatio="'+ devices[i].crop[j].preset[k].lockRatio +'" />');
  1948.                     }
  1949.  
  1950.                     indent='        ';
  1951.                     cf.WriteLine(indent +'</ratio>');
  1952.                 }
  1953.                 indent='    ';
  1954.                 cf.WriteLine(indent +'</crop>');
  1955.                 cf.WriteLine('</DEVICE>\r\n');
  1956.             }
  1957.  
  1958.             cf.close();
  1959.             pfso.DeleteFile("config_bak.xml");
  1960.             psfo=null;
  1961.         }
  1962.         catch(e)
  1963.         {
  1964.             if (cf)
  1965.                 cf.close();
  1966.  
  1967.             if (pfso)
  1968.             {
  1969.                 // Restore original in case of failure
  1970.                 pfso.CopyFile("config_bak.xml", "config.xml", true);
  1971.             }
  1972.             psfo=null;
  1973.              alert("Unable to save settings.\n\nError: "+ e.message);
  1974.         }
  1975.     }
  1976. }
  1977.  
  1978. function updateOutFileName()
  1979. {
  1980.     if (oF.format.value != "psp")
  1981.     {
  1982.         var t = oF.fName.value.match(/^(.*)\\(.+)\.[a-zA-Z0-9]+$/);
  1983.         if (t)
  1984.         {
  1985.             if (oF.format.value == "ipod")
  1986.                 oF.fName.value = t[1] +'\\'+ t[2] +'.mp4';
  1987.             else
  1988.                 oF.fName.value = t[1] +'\\'+ t[2] +'.'+ oF.format.value.toLowerCase();
  1989.         }
  1990.     }
  1991. }
  1992.  
  1993. // Load the saved optimized settings depending on width/height of source video and device capabilities
  1994. function optimize(isCropOnly)
  1995. {
  1996.     var i,j,k;
  1997.     if (!devices) getConfig(); // Retrieve the device configs
  1998.     for (i=0; i < devices.length; i++)
  1999.     {
  2000.         if (devices[i].name == oF.device.value)
  2001.             break;
  2002.     }
  2003.     currDevice = i;
  2004.     currDevName = devices[i].name;
  2005.     currDevLabel= devices[i].label;
  2006.  
  2007.     if (window.fileInput)
  2008.     {
  2009.         with(devices[i])
  2010.         {
  2011.             OvidCodec    = videoCodec;
  2012.             Oframerate    = frameRate;
  2013.             Obitrate    = videoBitRate;
  2014.             OaudCodec    = audioCodec;
  2015.             Ochannels    = audioChannels;
  2016.             OaudRate    = audioSampling;
  2017.             OaudBR        = audioBitRate;
  2018.             Ovol        = audioVolume;
  2019.         }
  2020.  
  2021.         if (!Ovol) Ovol = "100";
  2022.  
  2023.         if (oF.deviceQuality.value == "FULL")
  2024.         {
  2025.             Oframerate = (f.fRate.value);
  2026.         }
  2027.         else if (oF.deviceQuality.value == "HALF")
  2028.         {
  2029.             Oframerate = (f.fRate.value / 2);            
  2030.             Obitrate = 128;
  2031.         }
  2032.         else if (oF.deviceQuality.value == "THIRD")
  2033.         {
  2034.             Oframerate = (f.fRate.value / 2);
  2035.             Obitrate = 64;
  2036.         }
  2037.         else if (oF.deviceQuality.value == "FORTH")
  2038.         {
  2039.             Oframerate = (f.fRate.value / 2);
  2040.             Obitrate = 48;
  2041.         }
  2042.         // Resolution of Input Video
  2043.         var iWidth    = parseInt(f.resolution.value.substr(0,f.resolution.value.search('x')));
  2044.         var iHeight    = parseInt(f.resolution.value.substr(f.resolution.value.search('x')+1));
  2045.  
  2046.         // Fix any invalid ratios
  2047.         if (inRatio < 1)
  2048.         {
  2049.             inRatio = 1.3333;
  2050.             f.ratio.value = "4/3 ("+ inRatio +")";
  2051.         }
  2052.     }
  2053.  
  2054.     with (devices[i])
  2055.     {
  2056.         da.mdImage.src    = imageSrc;
  2057.         Oformat            = format;
  2058.         mdWidth            = parseInt(pixelWidth);
  2059.         mdHeight        = parseInt(pixelHeight);
  2060.         cropWinWidth    = parseInt(cropWidth);
  2061.         cropWinHeight    = parseInt(cropHeight);
  2062.         cropWinLeft        = parseInt(positionLeft);
  2063.         cropWinTop        = parseInt(positionTop);
  2064.     }
  2065.  
  2066.     for(j=0; j < devices[i].crop.length; j++)
  2067.     {
  2068.         if (inRatio > devices[i].crop[j].min)
  2069.         {
  2070.             k = cropPreset % devices[i].crop[j].preset.length;
  2071.             with(devices[i].crop[j].preset[k])
  2072.             {
  2073.                 Oresolution    = resolution;
  2074.                 OcropLeft    = cropLeft;
  2075.                 OcropRight    = cropRight;
  2076.                 OcropTop    = cropTop;
  2077.                 OcropBottom    = cropBottom;
  2078.                 OlockRatio  = (lockRatio != "NO");
  2079.             }
  2080.             currDevCrop = j;
  2081.             currDevPres = k;
  2082.             break;
  2083.         }
  2084.     }
  2085.  
  2086.     oF.devRes.value = mdWidth +"x"+ mdHeight;
  2087.  
  2088.     // Place CropCanvas
  2089.     var canvasPosObj = da.mdImage.offsetParent.offsetParent;
  2090.     var sty = da.cropCanvas.style;
  2091.     sty.top = canvasPosObj.offsetTop + cropWinTop;
  2092.     sty.left = canvasPosObj.offsetLeft + cropWinLeft;
  2093.     sty.width = cropWinWidth;
  2094.     sty.height = cropWinHeight;
  2095.     sty.visibility = "visible";
  2096.  
  2097.     if (!fileInput)
  2098.     {
  2099.         // Place CropTangle
  2100.         sty = da.cropTangle.style;
  2101.         sty.top = da.cropCanvas.offsetTop + 4;
  2102.         sty.left = da.cropCanvas.offsetLeft + 4;
  2103.         sty.width = da.cropCanvas.offsetWidth - 8;
  2104.         sty.height = da.cropCanvas.offsetHeight - 8;
  2105.         sty.visibility = "visible";
  2106.  
  2107.         // Place CropMovie
  2108.         sty = da.cropMovie.style;
  2109.         sty.top = da.cropCanvas.offsetTop + 20;
  2110.         sty.left = da.cropCanvas.offsetLeft;
  2111.         sty.width = da.cropCanvas.offsetWidth;
  2112.         sty.height = da.cropCanvas.offsetHeight - 40;
  2113.         sty.visibility = "visible";
  2114.  
  2115.         document.cropImage.width = da.cropCanvas.offsetWidth-2;
  2116.         document.cropImage.height = da.cropCanvas.offsetHeight - 40;
  2117.     }
  2118.  
  2119.     da.mdBorder.style.width    = cropWinWidth;
  2120.     da.mdBorder.style.height= cropWinHeight;
  2121.     da.mdBorder.style.top    = canvasPosObj.offsetTop + cropWinTop;
  2122.     da.mdBorder.style.left    = canvasPosObj.offsetLeft + cropWinLeft;
  2123.  
  2124.     // Set optimized settings
  2125.     if (fileInput)
  2126.     {
  2127.         var xPos = Oresolution.indexOf('x');
  2128.         oF.resolutionW.value= Oresolution.substr(0,xPos);
  2129.         oF.resolutionH.value= Oresolution.substr(xPos+1);
  2130.         oF.cropLeft.value    = OcropLeft;
  2131.         oF.cropRight.value    = OcropRight;
  2132.         oF.cropTop.value    = OcropTop;
  2133.         oF.cropBottom.value    = OcropBottom;
  2134.         oF.format.value        = Oformat;
  2135.  
  2136.         if (devices[i].name == "PSP")
  2137.             oF.fName.value = outPath +'\\'+ getPspName();
  2138.         else
  2139.             updateOutFileName();
  2140.  
  2141.         if (!isCropOnly)
  2142.         {
  2143.             oF.vCodec.value        = OvidCodec;
  2144.             oF.aCodec.value        = OaudCodec;
  2145.             oF.vRate.value        = Obitrate;
  2146.             oF.aRate.value        = OaudBR;
  2147.             oF.sampling.value    = OaudRate;
  2148.             oF.fRate.value        = oF.fRate.lastValue = Oframerate;  // Remember the initial value of the Frame Rate
  2149.             if (Ochannels == 1)
  2150.                 oF.channels[1].click();
  2151.             else
  2152.                 oF.channels[0].click();
  2153.             oF.volume.value        = Ovol;
  2154.             oF.lockRatio.checked= OlockRatio;
  2155.         }
  2156.  
  2157.         oF.encodeBtn.disabled    = false;
  2158.         oF.encodeBtn.className    = "goOn";
  2159.         oF.batchBtn.disabled = false;
  2160.         oF.batchBtn.className = "batchOn";
  2161.         oF.abortBtn.className    = "abortOff";
  2162.         oF.encodeBtn.src="images/start_1.jpg";
  2163.  
  2164.         adjustCrop(oF.resolutionW, true);
  2165.  
  2166.         if (parseInt(oF.recEnd.value) > 0) estimateSize();
  2167.  
  2168.         getScreenShot(shotPos);
  2169.     }
  2170.     saveVemodeSettings();
  2171.     devices=null;
  2172. }
  2173.  
  2174. // Adjust Crop Sceen depending on settings Window
  2175. function adjustCrop(obj, fixDevice)
  2176. {
  2177.     if (obj != oF.lockRatio && (obj.value == "" || isNaN(obj.value)))
  2178.         obj.value = 1;
  2179.  
  2180.     if (oF.fName.value=="" || isNaN(oF.resolutionW.value) || isNaN(oF.resolutionH.value)
  2181.         || isNaN(oF.cropLeft.value) || isNaN(oF.cropRight.value)
  2182.         || isNaN(oF.cropTop.value) || isNaN(oF.cropBottom.value))
  2183.         return;
  2184.  
  2185.     // Enforce locking of Aspect Ratio
  2186.     if (oF.lockRatio.checked)
  2187.     {
  2188.  
  2189.         if (obj == oF.cropLeft)
  2190.             oF.cropRight.value = oF.cropLeft.value;
  2191.         else if (obj == oF.cropRight)
  2192.             oF.cropLeft.value = oF.cropRight.value;
  2193.         else if (obj == oF.cropTop)
  2194.             oF.cropBottom.value = oF.cropTop.value;
  2195.         else if (obj == oF.cropBottom)
  2196.             oF.cropTop.value = oF.cropBottom.value;
  2197.  
  2198.         // Change the Height when others are changed unless the Height itself has changed
  2199.         // NOTE: We make Height and Weight a multiple of 2
  2200.         /*if (obj == oF.resolutionH || obj == oF.cropLeft || obj == oF.cropRight)
  2201.         {
  2202.             oF.resolutionH.value = Math.round(oF.resolutionH.value / 2) * 2;
  2203.             oF.resolutionW.value = Math.round((parseInt(oF.resolutionH.value) + parseInt(oF.cropTop.value) + parseInt(oF.cropBottom.value)) * inRatio /2)*2 - oF.cropLeft.value - oF.cropRight.value;
  2204.  
  2205.             if (parseInt(oF.resolutionW.value) < 0)
  2206.             {
  2207.                 oF.resolutionW.value = 0-oF.resolutionW.value;
  2208.                 adjustCrop(oF.resolutionW);
  2209.             }
  2210.         }
  2211.         else
  2212.         {
  2213.             if (obj == oF.resolutionW)
  2214.                 oF.resolutionW.value = Math.round(oF.resolutionW.value / 2) * 2;
  2215.             oF.resolutionH.value = Math.round((parseInt(oF.resolutionW.value) + parseInt(oF.cropLeft.value) + parseInt(oF.cropRight.value)) / inRatio /2)*2 - oF.cropTop.value - oF.cropBottom.value;
  2216.  
  2217.             if (parseInt(oF.resolutionH.value) < 0)
  2218.             {
  2219.                 oF.resolutionH.value = 0-oF.resolutionH.value;
  2220.                 adjustCrop(oF.resolutionH);
  2221.             }
  2222.         }*/
  2223.  
  2224.         // If the Width creates a crop that is higher than the decice height, use the device height as the max
  2225.         //if (fixDevice && parseInt(oF.resolutionH.value) > mdHeight)
  2226.         //{
  2227.         //    oF.resolutionH.value = mdHeight;
  2228.         //    if (parseInt(oF.cropLeft.value) > 0)
  2229.         //        oF.cropLeft.value = parseInt(oF.cropLeft.value)
  2230.         //    adjustCrop(oF.resolutionH);
  2231.         //}
  2232.     }
  2233.  
  2234.     // Resolution of Output
  2235.     var oWidth = parseInt(oF.resolutionW.value);
  2236.     var oHeight= parseInt(oF.resolutionH.value);
  2237.  
  2238.     // Modifier Factor to scale the images to the size of the PDA image
  2239.     var modFactorW = mdWidth / cropWinWidth;
  2240.     var modFactorH = mdHeight / cropWinHeight;
  2241.  
  2242.     // Actual size of the movie on our page after applying cropping
  2243.     var cWidth  = Math.round((oWidth  + parseInt(oF.cropLeft.value) + parseInt(oF.cropRight.value)) / modFactorW);
  2244.     var cHeight = Math.round((oHeight + parseInt(oF.cropTop.value)  + parseInt(oF.cropBottom.value)) / modFactorH);
  2245.  
  2246.      document.cropImage.width = cWidth-2;
  2247.     document.cropImage.height = cHeight-2;
  2248.  
  2249.     da.cropMovie.style.width = cWidth;
  2250.     da.cropMovie.style.height = cHeight;
  2251.  
  2252.     // Now get the size of the crop rectangle (which corresponds to the output resolution)
  2253.     cWidth = Math.round(oWidth  / modFactorW);
  2254.     cHeight= Math.round(oHeight / modFactorH);
  2255.     da.cropTangle.style.width = cWidth;
  2256.     da.cropTangle.style.height = cHeight;
  2257.     da.cropTangle.style.top = (da.cropCanvas.offsetTop + ((cropWinHeight - cHeight)+.5) / 2);
  2258.     da.cropTangle.style.left = (da.cropCanvas.offsetLeft + ((cropWinWidth - cWidth)+.5) / 2);
  2259.  
  2260.     // Now position the movie relative to crop rectangle
  2261.     da.cropMovie.style.top = da.cropTangle.offsetTop   - parseInt(oF.cropTop.value) / modFactorH;//  + parseInt(oF.cropBottom.value);
  2262.     da.cropMovie.style.left = da.cropTangle.offsetLeft - parseInt(oF.cropLeft.value)/ modFactorW;// + parseInt(oF.cropRight.value);
  2263. }
  2264.  
  2265. function blank()
  2266. {
  2267.     return;
  2268. }
  2269.  
  2270. // Adds a video to the batch process
  2271. function batchEncode(refresh)
  2272. {
  2273.     if (isMultiVOB && f.lang && f.lang.value == "-1")
  2274.     {
  2275.         alert("Please select an Audio Track so that the DVD is prepared for encoding.");
  2276.         ssSyncOptions(f.lang);
  2277.         return;
  2278.     }
  2279.  
  2280.     // Prevent multiple calls
  2281.     if (da.popMsg && da.popMsg.lastName == 'pBatch' && da.popMsg.style.visibility == "visible")
  2282.         return;
  2283.  
  2284.     var hasOne=false;
  2285.  
  2286.     if (!numInQ)
  2287.     {
  2288.         batchQ = new Array();
  2289.     }
  2290.  
  2291.     if (!refresh)
  2292.         encode(false,"ADD");
  2293.  
  2294.     var html = '<table bgcolor="#FFFFBB" cellpadding=5 cellspacing=0 width=540><tr><td>'
  2295.         +'<H4>Encoding Queue</H4>'
  2296.         +'This is the list of videos that are prepared for encoding. When you are ready to convert these videos, press'
  2297.         +' the <b>Encode Queue!</b> button bellow.<BR><BR>';
  2298.  
  2299.     for(var i=0; i < numInQ; i++)
  2300.     {
  2301.         if (batchQ[i] && !batchQ[i].deleted && !batchQ[i].hide)
  2302.         {
  2303.             if (!hasOne)
  2304.             {
  2305.                    html += '<table border=0 cellpadding=2 cellspacing=1 bgcolor="#006600" width="500">'
  2306.                     +'<tr bgcolor="white"><th></th><th>File</th><th>Duration</th><th>Est. Size</th></tr>';
  2307.                 hasOne = true;
  2308.             }
  2309.  
  2310.                html += '<tr bgcolor="white"><td align="center"><a href="#" onclick="batchDelete('+ i +')">remove</a></td>'
  2311.                 +'<td>'+ batchQ[i].fName +'</td>'
  2312.                 +'<td align="center">'+ batchQ[i].Duration +'</td>'
  2313.                 +'<td align="center">'+ batchQ[i].EstSize + ((batchQ[i].multi) ? ' (Split)' : '') +'</td></tr>';
  2314.         }
  2315.     }
  2316.  
  2317.     if (!hasOne)
  2318.     {
  2319.         if (numInQ > 0)
  2320.         {
  2321.             numInQ = 0;
  2322.             batchQ = null;
  2323.         }
  2324.         return;
  2325.     }
  2326.     
  2327.     html += '</table><br><input name="encodeAllBtn" class="goOn" type=button value="Encode Queue!" onclick="encodeAll()">'
  2328.         +'<br><br><center>[<a href="#" onclick="closeMessage(\'pBatch\')">Close</a>]</center></td></tr></table>';
  2329.  
  2330.     //if (document.Player1.enabled)
  2331.     //{
  2332.     //    toggleActive(document.Player1);
  2333.     //    window.enablePreviewOnClose=true;
  2334. //    }
  2335.     popMessage('pBatch',html,true, 60, 30);
  2336. }
  2337.  
  2338. function batchDelete(idx)
  2339. {
  2340.     if (batchQ[idx])
  2341.     {
  2342.         batchQ[idx].deleted=true;
  2343.         var i = idx+1;
  2344.         while(i < numInQ && batchQ[i] && batchQ[i].hide)
  2345.         {
  2346.             batchQ[i].deleted = true;
  2347.             i++;
  2348.         }
  2349.     }
  2350.     closeMessage('pBatch', true);
  2351.     batchEncode(true);
  2352. }
  2353.  
  2354. // Starts the bach encoding process
  2355. function encodeAll(lastStep)
  2356. {
  2357.     window.nextDone=null;
  2358.     closeMessage('pBatch');
  2359.     if (!lastStep) batchProgress++;
  2360.     var i = batchProgress;
  2361.  
  2362.     // Skip deleted items
  2363.     while (i < numInQ && batchQ[i] && batchQ[i].deleted)
  2364.         i++;
  2365.  
  2366.     if (i >= numInQ)
  2367.     {
  2368.         batchProgress = -1;
  2369.         batchCurrFile = 0;
  2370.         encodingComplete();
  2371.         numInQ = 0;
  2372.         batchQ = null;
  2373.         batchProgress = -1;
  2374.         return;
  2375.     }
  2376.  
  2377.     if (batchQ[i])
  2378.     {
  2379.         try
  2380.         {
  2381.             secOutPath = batchQ[i].secOutPath;
  2382.  
  2383.             // Index DVD
  2384.             if (isMultiVOB)
  2385.             {
  2386.                 if (lastStep != "INDEX" && lastStep != "SUB" && batchQ[i].indexCmd)
  2387.                 {
  2388.                     window.indexShell = new ActiveXObject( "WScript.shell" );
  2389.                     if (batchQ[i].EstSize<2)
  2390.                         ff.outSize.value = batchQ[i].EstSize;
  2391.                     else
  2392.                         ff.outSize.value = batchQ[i].EstSize - 1;
  2393.                     indexShell.run( batchQ[i].indexCmd, 0, false );
  2394.                     window.outStream=null;
  2395.  
  2396.                     // Start tracking progress on the indexing
  2397.                     oF.encodeBtn.disabled = true;
  2398.                     oF.encodeBtn.className = "goOff";
  2399.                     oF.abortBtn.className = "abortOn";
  2400.                     oF.encodeBtn.src="images/start_on.jpg";
  2401.                     oF.batchBtn.disabled = true;
  2402.                     oF.batchBtn.className = "goOff";
  2403.                     window.nextDone = "INDEX";
  2404.                     window.lastIPos=null;
  2405.                     setTimeout("indexProgress(1)", 1000);
  2406.                     return;
  2407.                 }
  2408.  
  2409.                 if (lastStep != "SUB" && batchQ[i].subCmd)
  2410.                 {
  2411.                     window.vsShell = new ActiveXObject( "WScript.shell" );
  2412.                     vsShell.run( batchQ[i].subCmd, 0, false );
  2413.                     window.outStream=null;
  2414.  
  2415.                     // Start tracking progress on the sub extraction
  2416.                     ff.txtOut.value = "Extracting Subtitles from DVD...";
  2417.                     oF.encodeBtn.disabled = true;
  2418.                     oF.encodeBtn.className = "goOff";
  2419.                     oF.abortBtn.className = "abortOn";
  2420.                     oF.encodeBtn.src="images/start_on.jpg";
  2421.                     oF.batchBtn.disabled = true;
  2422.                     oF.batchBtn.className = "goOff";
  2423.                     window.nextDone = "SUB";
  2424.                     window.lastSPos=null;
  2425.                     setTimeout("subtProgress(1)", 1000);
  2426.                     return;
  2427.                 }
  2428.             }
  2429.  
  2430.             // Encode
  2431.             multi_pass = multi_num = lastPartProgPos = 0;
  2432.             if(batchQ[i].part < 2)
  2433.                 batchCurrFile++;
  2434.             window.encodeShell = new ActiveXObject( "WScript.shell" );
  2435.             if (batchQ[i].EstSize<2)
  2436.                 ff.outSize.value = batchQ[i].EstSize;
  2437.             else
  2438.                 ff.outSize.value = batchQ[i].EstSize - 1;
  2439.             encodeShell.run( batchQ[i].encString, 0, false );
  2440.             window.outStream=null;
  2441.          }
  2442.          catch(e)
  2443.          {
  2444.              window.encodeShell = null;
  2445.              window.indexShell = null;
  2446.              window.subShell = null;
  2447.              alert("Error during batch encoding: "+ e.message);
  2448.              return;
  2449.          }
  2450.  
  2451.         // Start tracking progress on the encoding
  2452.         oF.encodeBtn.disabled = true;
  2453.         oF.encodeBtn.className = "goOff";
  2454.         oF.batchBtn.disabled = false;
  2455.         oF.abortBtn.className = "abortOn";
  2456.         oF.encodeBtn.src="images/start_on.jpg";
  2457.         oF.batchBtn.className = "goOff";
  2458.  
  2459.         setTimeout("progress(1)", 3000);
  2460.     }
  2461. }
  2462.  
  2463. // Start the conversion process
  2464. function encode(pass, batchAction, isAfterIndex)
  2465. {
  2466.     // When we have a Batch Queue, display the Queue instead
  2467.     if (!batchAction && batchQ && numInQ > 0)
  2468.     {
  2469.         batchEncode(true);
  2470.         return;
  2471.     }
  2472.  
  2473.     /*
  2474.     if (isMultiVOB && f.lang && f.lang.value == "-1")
  2475.     {
  2476.         alert("Please select an Audio Track so that the DVD is prepared for encoding.");
  2477.         ssSyncOptions(f.lang);
  2478.         return;
  2479.     }
  2480.     */
  2481.  
  2482.     var fName = (fileInput) ? fileInput : "";
  2483.     var oFile = oF.fName.value;
  2484.     var recs=null, rece=null;
  2485.     if (!fName || !oFile) return;
  2486.  
  2487.      var m = fName.match(/\\([^\\.]+)\./);
  2488.      
  2489.     var nParts, hasErrors = false;
  2490.     var audioTrack = (f.lang && f.lang.style.visibility != "hidden" && parseInt(1*f.lang.value) > 0) ? f.lang.value : audioMap;
  2491.  
  2492.     if (!pass)
  2493.     {
  2494.         multi_pass = multi_num = lastPartProgPos = 0;
  2495.         da.instLink.style.visibility = "hidden";
  2496.     }
  2497.     else
  2498.         lastPartProgPos = progPos;  // Remember the progress position from the last part
  2499.  
  2500.     // Multiple passes when splitting the output file
  2501.     if (oF.splitTo.value != "")
  2502.     {
  2503.         if (!pass)
  2504.         {
  2505.             multi_num = Math.ceil((1+parseInt(oF.fixSize.value)) / parseInt(oF.splitTo.value));
  2506.             pass = multi_pass = 1;
  2507.         }
  2508.  
  2509.         // Determine the start and end positions that match our split selection
  2510.         var totSec = oF.recEnd.value - parseInt(oF.recStart.value);
  2511.         var br = parseInt(oF.vRate.value) + parseInt(oF.aRate.value);
  2512.         var siz = parseInt(oF.splitTo.value) * 1024;
  2513.         var splitSec = Math.floor(siz / (br/8));
  2514.  
  2515.         if (pass == 1)
  2516.             recs = (oF.recStart && oF.recStart.value > 0) ? oF.recStart.value : "0";
  2517.         else
  2518.             recs = (pass-1) * splitSec;
  2519.  
  2520.         if (pass == multi_num)
  2521.         {
  2522.             // Note: "rece" actually stores the number of video frames to record
  2523.             rece = (oF.recEnd && oF.recStart && parseInt(oF.recEnd.value) < inTarget && parseInt(oF.recStart.value) < parseInt(oF.recEnd.value)) ? Math.round((parseInt(oF.recEnd.value) - recs) * oF.fRate.value,1) : "@";
  2524.         }
  2525.         else
  2526.         {
  2527.             if ((pass * splitSec) >= parseInt(oF.recEnd.value))
  2528.             {
  2529.                 rece = "@";
  2530.                 multi_num = pass;
  2531.             }
  2532.             else
  2533.             {
  2534.                 rece = Math.round(splitSec * oF.fRate.value,1);
  2535.             }
  2536.         }
  2537.     }
  2538.     // Generate the multiple passes for multi-part VOBs
  2539.     else if (isMultiVOB && false)  // todo remove
  2540.     {
  2541.          outTitle = (m) ? m[1] : "MediaCell Video";
  2542.         outTitle = outTitle.replace(/_/g, ' ');
  2543.  
  2544.         m = fName.match(/^(.+)\\(vts_.*)$/i);
  2545.         if (m)
  2546.         {
  2547.             vobPath = m[1];
  2548.             if (!pass)
  2549.             {
  2550.                 nParts = 1;
  2551.                 window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  2552.                 while(nParts < 10)
  2553.                 {
  2554.                     if (!pfso.FileExists( fName.replace(/_\d+\.vob$/i, "_"+ nParts +".vob") ))
  2555.                     {
  2556.                         nParts--;
  2557.                         break;
  2558.                     }
  2559.                     nParts++;
  2560.                 }
  2561.                 if (nParts < 1) return;
  2562.                 pfso=null;
  2563.  
  2564.                 multi_num = nParts;
  2565.                 pass = multi_pass = 1;
  2566.             }
  2567.  
  2568.             // Determine the start and end positions that match our split input files
  2569.             recs = (pass == 1 && oF.recStart && oF.recStart.value > 0) ? oF.recStart.value : "0";
  2570.  
  2571.             if (pass == multi_num)
  2572.             {
  2573.                 // Note: "rece" actually stores the number of video frames to record
  2574.                 rece = (oF.recEnd && oF.recStart && parseInt(oF.recEnd.value) < inTarget && parseInt(oF.recStart.value) < parseInt(oF.recEnd.value)) ? Math.round((parseInt(oF.recEnd.value) - lastPartProgPos) * oF.fRate.value,1) : "@";
  2575.             }
  2576.             else
  2577.             {
  2578.                 rece = "@";
  2579.                 
  2580.                 // This should not happen since progress() will abort the encoding when it reaches recEnd
  2581.                 if (lastPartProgPos >= parseInt(oF.recEnd.value))
  2582.                     multi_num = pass;
  2583.             }
  2584.         }
  2585.         else
  2586.             return;
  2587.     }
  2588.  
  2589.     // Rename the file and the title to indicate the parts
  2590.     if (multi_num > 0)
  2591.     {
  2592.         fName = fName.replace(/_\d+\.vob$/i, "_"+ pass +".vob");
  2593.         if (oF.format.value=="psp")
  2594.         {
  2595.             // PSP is specific about the file names, so we regenerate a new file name using the next sequential number
  2596.             if (pass > 1)
  2597.             {
  2598.                 oFile = outPath +'\\'+ getPspName(oFile);
  2599.             }
  2600.         }
  2601.         else
  2602.             oFile = oFile.replace(/\.[^\.]+$/,"_p"+ pass +"."+ oF.format.value.toLowerCase());
  2603.  
  2604.         if (multi_pass > 1)
  2605.             outTitle = outTitle.replace(/ p\d+$/, " p"+ multi_pass);
  2606.         else
  2607.             outTitle = outTitle.replace(/ p\d+$/,"") +" p"+ multi_pass;
  2608.     }
  2609.     
  2610.     // Check for existing file
  2611.     try
  2612.     {
  2613.         if (!isAfterIndex && (multi_num < 1 || pass == 1))
  2614.         {
  2615.             window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  2616.             if(pfso.FileExists(oFile))
  2617.             {
  2618.                 var answer = askYesNoCancel("This output file already exists. Do you wish to overwrite it?");
  2619.                 if (answer != 6) // If not Yes
  2620.                     return;
  2621.             }
  2622.  
  2623.             // Make sure the output folder is created
  2624.             if (!pfso.FolderExists(outPath))
  2625.                 pfso.CreateFolder(outPath);
  2626.  
  2627.             pfso=null;
  2628.         }
  2629.     }
  2630.     catch(e)
  2631.     {
  2632.          pfso=null;
  2633.          alert("Error checking for existing file: "+ e.message);
  2634.          return;
  2635.      }
  2636.  
  2637.     // Before we encode, we need to index the DVD
  2638.     if (!pass && isMultiVOB && f.lang && f.lang.value != "" && !indexComplete)
  2639.     {
  2640.         indexDVD(batchAction);
  2641.  
  2642.         if (!batchAction) return;  // When indexDVD() is complete, it will re-call encode()
  2643.     }
  2644.     // Now, check if we need to extract subtitles
  2645.     else if (!pass && isMultiVOB && f.subt && f.subt.value != "" && !window.vsCfg)
  2646.     {
  2647.         grabSubtitles(batchAction);
  2648.         if (!batchAction) return;  // When complete, grabSubtitles will call indexDVD() again
  2649.     }
  2650.     else
  2651.     {
  2652.         window.lastIndexCmd = null;
  2653.         window.lastSubCmd = null;
  2654.     }
  2655.  
  2656.     if (batchAction != "ADD")
  2657.     {
  2658.         oF.encodeBtn.disabled = true;
  2659.         oF.encodeBtn.className = "goOff";
  2660.         oF.abortBtn.className = "abortOn";
  2661.         oF.encodeBtn.src="images/start_on.jpg";
  2662.         oF.batchBtn.disabled = true;
  2663.         oF.batchBtn.className = "goOff";
  2664.     }
  2665.  
  2666.     try
  2667.     {
  2668.         // Run MediaCellEngine in a separate process
  2669.         window.encodeShell = new ActiveXObject( "WScript.shell" );
  2670.  
  2671.         if (parseInt(1*oF.resolutionW.value) < 1 || parseInt(1*oF.resolutionH.value) < 1 || parseInt(1*oF.fRate.value) < 1
  2672.              || parseInt(1*oF.vRate.value) < 1 || parseInt(1*oF.sampling.value) < 1 || isNaN(parseInt(oF.aRate.value))
  2673.              || oF.vCodec.value == "" || oF.aCodec.value == "")
  2674.         {
  2675.             //alert("Invalid Encoding Settings");
  2676.             //oF.encodeBtn.disabled = false;
  2677.             //oF.encodeBtn.className = "goOn";
  2678.             //oF.batchBtn.disabled = false;
  2679.             //oF.batchBtn.className = "batchOn";
  2680.             //oF.abortBtn.className = "abortOff";
  2681.             //oF.encodeBtn.src="images/start_1.jpg";
  2682.             //oF.document.all.progr.innerHTML = "";
  2683.             //encodeShell=null;
  2684.             //pfso=null;
  2685.             //return;
  2686.             oF.resolutionW.value = 320;
  2687.             oF.resolutionH.value = 240;
  2688.             //oF.fRate.value = 25;
  2689.             oF.vRate.value = 1024;
  2690.             oF.sampling.value = 16;
  2691.             oF.aRate.value = 48;
  2692.             oF.vCodec.value = "mpg";
  2693.             oF.aCodec.value = "mp3";
  2694.             oF.volume.value = 100;
  2695.         }
  2696.  
  2697.         // Apply zoom factor between original video and new video, so that cropping is based on original pixel size
  2698.         var iWidth = parseInt(f.resolution.value.substr(0,f.resolution.value.search('x')));
  2699.         var zoomFactorX = iWidth / parseInt(1*oF.resolutionW.value + 1*oF.cropLeft.value + 1*oF.cropRight.value);
  2700.  
  2701.         var iHeight= parseInt(f.resolution.value.substr(f.resolution.value.search('x')+1));
  2702.         var zoomFactorY = iHeight / parseInt(1*oF.resolutionH.value + 1*oF.cropTop.value + 1*oF.cropBottom.value);
  2703.  
  2704.         var cL = parseInt(oF.cropLeft.value*zoomFactorX);
  2705.         var cR = parseInt(oF.cropRight.value*zoomFactorX);
  2706.         var cT = parseInt(oF.cropTop.value*zoomFactorY);
  2707.         var cB = parseInt(oF.cropBottom.value*zoomFactorY);
  2708.  
  2709.         if (cL % 2 == 1) cL -= 1;
  2710.         if (cR % 2 == 1) cR -= 1;
  2711.         if (cT % 2 == 1) cT -= 1;
  2712.         if (cB % 2 == 1) cB -= 1;
  2713.  
  2714.         // Prepare start and end pos recording
  2715.         if (!recs) recs=(oF.recStart && oF.recStart.value > 0) ? oF.recStart.value : "0";
  2716.  
  2717.         // Note: "rece" actually stores the number of video frames to record
  2718.         if (!rece) rece=(oF.recEnd && oF.recStart && parseInt(oF.recEnd.value) < inTarget && parseInt(oF.recStart.value) < parseInt(oF.recEnd.value)) ? Math.round((parseInt(oF.recEnd.value)-parseInt(oF.recStart.value)) * oF.fRate.value,1) : "@";
  2719.  
  2720.         recDuration = parseInt(oF.recEnd.value)-parseInt(oF.recStart.value);
  2721.         partDuration = (rece == '@') 
  2722.             ? (inTarget - recs)
  2723.             : parseInt(rece / parseInt(oF.fRate.value));
  2724.  
  2725.         ffInputFile = fName;//checkAVS(fName, true);
  2726.  
  2727.         // For AVS files, the audio stream is always the mapped one
  2728.         if (ffInputFile.search(/\.avs$/i) > 0)
  2729.             audioTrack = audioMap;
  2730.  
  2731.         // For PSP format, create the thumbnail picture
  2732.         if (oF.format.value == "psp" && oFile.search(/\.MP4$/i) > 0)
  2733.             encodeShell.run( '%comspec% /c .\\Engine\\MediaCellEngine.exe -ss '+ ((shotPos) ? shotPos : 10) +' -i "'+ ffInputFile +'" -y -f mjpeg -vframes 1 -s 160x120 -an "'+ oFile.replace(/\.mp4$/i,'.THM') +'" > .\\mmshot 2>&1', 0, true );
  2734.  
  2735.         // Generate the encoding command
  2736.         var encString = '%comspec% /c .\\enc.bat "'+ ffInputFile +'" '+ oF.vCodec.value
  2737.             +' '+ videoMap +' '+ audioTrack +' '+ oF.volume.value +' "'+ outTitle +'" "'+ getEncDate() +'" '+ cL +' '+ cR
  2738.                 +' '+ cT +' '+ cB +' '+ recs +' '+ rece
  2739.             +' '+ (oF.resolutionW.value +'x'+ oF.resolutionH.value) +' '+ oF.fRate.value +' '+ oF.vRate.value*800
  2740.             +' '+ oF.aCodec.value +' '+ ((oF.channels[1].checked) ? 1 : 2)
  2741.             +' '+ oF.sampling.value +' '+ oF.aRate.value +' '+ oF.format.value +' "'+ oFile +'"';
  2742.         
  2743.         //alert(encString);
  2744.         // Prepare the Batch Process
  2745.         if (batchAction == "ADD")
  2746.         {
  2747.             batchQ[numInQ] = new Object();
  2748.             if (multi_pass > 1)
  2749.             {
  2750.                 batchQ[numInQ].hide = true;
  2751.                 batchQ[numInQ].master = masterBatchIdx;
  2752.             }
  2753.             else
  2754.             {
  2755.                 var m = oFile.match(/^(.*)\\(.+)\.([a-zA-Z0-9]+)$/);
  2756.                 if (m)
  2757.                     batchQ[numInQ].fName = m[2].replace(/_p1$/,"") +'.'+ m[3];
  2758.  
  2759.                 batchQ[numInQ].Duration = oF.outLength.value;
  2760.                 batchQ[numInQ].EstSize = ff.outSize.value;
  2761.                 masterBatchIdx = numInQ;
  2762.                 batchQ[numInQ].multi = (multi_pass==1);
  2763.             }
  2764.             batchQ[numInQ].recDuration = recDuration;
  2765.             batchQ[numInQ].partDuration = partDuration;
  2766.             batchQ[numInQ].part = multi_pass;
  2767.             batchQ[numInQ].encString = encString;
  2768.             batchQ[numInQ].indexCmd = window.lastIndexCmd;
  2769.             batchQ[numInQ].subCmd = window.lastSubCmd;
  2770.             batchQ[numInQ].secOutPath = secOutPath;
  2771.             numInQ++;
  2772.  
  2773.             encodeShell=null;
  2774.             pfso=null;
  2775.  
  2776.             if (multi_num > 0 && multi_pass < multi_num)
  2777.             {
  2778.                 multi_pass++;
  2779.                 encode(multi_pass, "ADD");
  2780.                 return;
  2781.             }
  2782.             return;
  2783.         }
  2784.  
  2785.         // Encode
  2786.         encodeShell.run( encString, 0, false );
  2787.         window.outStream=null;
  2788.      }
  2789.      catch(e)
  2790.      {
  2791.         window.encodeShell = null;
  2792.          alert("Error before encoding: "+ e.message);
  2793.          return;
  2794.      }
  2795.  
  2796.     // Start tracking progress on the encoding
  2797.     setTimeout("progress(1)", 3000);
  2798. }
  2799.  
  2800. function OpenHelpProg()
  2801. {
  2802.     window.encodeShell = new ActiveXObject( "WScript.shell" );
  2803.     encodeShell.run( '%comspec% /c .\\help.chm', 0, false);
  2804.     encodeShell=null;
  2805. }
  2806.  
  2807. // Track progress of the encoding
  2808. function progress(isStart)
  2809. {
  2810.     var hasAborted = (ff.txtOut.value.search(/Encoding Aborted/) == 0);
  2811.  
  2812.     if (!window.outStream)
  2813.     {
  2814.         window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  2815.         window.outStream = pfso.OpenTextFile('.\\MediaCellEngine.log');
  2816.     }
  2817.     var m, pos, line = String();
  2818.     var atEnd = outStream.atEndOfStream;
  2819.     if( !atEnd && (line = outStream.Read(4000)) )
  2820.     {
  2821.         if (isStart && line.search(/frame=/) < 0)
  2822.         {
  2823.             if (line.search(/[\r\n]A>/) >= 0 || isStart > 14)
  2824.             {
  2825.                 alert("Error:\n\n"+ line);
  2826.                 oF.encodeBtn.disabled = false;
  2827.                 oF.encodeBtn.className = "goOn";
  2828.                 oF.batchBtn.disabled = false;
  2829.                 oF.batchBtn.className = "batchOn";
  2830.                 oF.abortBtn.blur();
  2831.                 oF.abortBtn.className = "abortOff";
  2832.                 ff.txtOut.value = 'Encoding Aborted.';
  2833.                 return;
  2834.             }
  2835.  
  2836.             // Give it a second and try again
  2837.             setTimeout("progress("+ (isStart+1) +")", 1000);
  2838.         }
  2839.  
  2840.         m = line.match(/time=([^\s\t]+)/);
  2841.         if (m)
  2842.         {
  2843.             progPos = parseFloat(m[1]) + lastPartProgPos;
  2844.  
  2845.             // If we reached the desired End position on a multi-part DVD encoding, abort the encoding after 2 min, just so it doesn't go on forever
  2846.             if (batchProgress < 0 && !hasAborted && isMultiVOB && progPos >= (parseInt(oF.recEnd.value)+120))
  2847.             {
  2848.                 multi_pass = multi_num;
  2849.                 abort(true);
  2850.                 return;
  2851.             }
  2852.  
  2853.             var tmpRecDur, tmpPartDur;
  2854.             if (batchProgress >= 0 && batchQ[batchProgress])
  2855.             {
  2856.                 tmpRecDur = batchQ[batchProgress].partDuration - 1;
  2857.                 tmpPartDur = batchQ[batchProgress].partDuration;
  2858.             }
  2859.             else
  2860.             {
  2861.                 tmpRecDur = recDuration;
  2862.                 tmpPartDur = recDuration;
  2863.             }
  2864.  
  2865.             pos = Math.round(progPos / tmpRecDur * 100);
  2866.  
  2867.             if (pos > 100) pos = 100;
  2868.             //oF.document.all.progr.innerHTML = pos +"%";
  2869.             if (!hasAborted)
  2870.                 if (batchProgress >= 0)
  2871.                     ff.txtOut.value = "Encoding File # "+ batchCurrFile + ((batchQ[batchProgress] && batchQ[batchProgress].part) ? " Part "+ batchQ[batchProgress].part : "") +" : " + pos +"%";
  2872.                 else
  2873.                     ff.txtOut.value = "Encoding"+ ((multi_num > 0) ? " Part "+multi_pass : "") + ": " + pos +"%";
  2874.  
  2875.             da.progBar.style.width = pos +"%";
  2876.  
  2877.             if (startTm)
  2878.             {
  2879.                 encTimer = new Date();
  2880.                 var elapsed = (encTimer.getTime() - startTm);
  2881.                 var remains = Math.round(elapsed * tmpPartDur / progPos) - elapsed;
  2882.                 var showSec = ((remains/60000) < 5); // Show seconds only when 5 minutes or less remain
  2883.  
  2884.                 if ((elapsed - lastElapsed) > 500)
  2885.                 {
  2886.                     lastElapsed = elapsed;
  2887.                     var elF = formatZero(Math.floor(remains / 3600000),2); // 1000ms * 60sec * 60min
  2888.                     remains -= Math.floor(remains / 3600000) * 3600000;
  2889.                     elF += ":"+ formatZero(Math.floor(remains / 60000),2);  // 1000ms * 60sec
  2890.                     remains -= Math.floor(remains / 60000) * 60000;
  2891.                     if (showSec)
  2892.                         elF += ":"+ formatZero(Math.floor(remains / 1000),2);
  2893.                     else
  2894.                         elF += ":00";
  2895.                     ff.recTime.value = elF;
  2896.                     encTimer = null;
  2897.                 }
  2898.             }
  2899.             m=null;
  2900.  
  2901.             /*
  2902.             // Show encoding progress within the media player
  2903.             if (isPlayerPaused)
  2904.                 with (document.Player1)
  2905.                 {
  2906.                     controls.currentPosition = currentMedia.duration * pos / 100;
  2907.                     controls.pause();
  2908.                 }
  2909.             */
  2910.         }
  2911.     }
  2912.  
  2913.     if (isStart)
  2914.     {
  2915.         if (multi_num < 1 || multi_pass == 1)
  2916.         {
  2917.             ff.txtOut.value = "Encoding...";
  2918.             da.progCanvas.style.visibility = "visible";
  2919.             da.progBar.style.width = "0%";
  2920.             da.progBar.style.backgroundColor = "#FFA000";
  2921.             encTimer = new Date();
  2922.             startTm = encTimer.getTime();
  2923.             encTimer = null;
  2924.             lastElapsed = 0;
  2925.             lastPartProgPos=0;
  2926.         }
  2927.     }
  2928.  
  2929.     if (line && (line.search(/video\:[0-9]+kB\s+audio\:/) >= 0 || line=="ERROR"))
  2930.     {
  2931.         if (hasAborted)
  2932.             multi_pass = multi_num;
  2933.         else
  2934.         {
  2935.             oF.encodeBtn.disabled = false;
  2936.             oF.encodeBtn.className = "goOn";
  2937.             oF.batchBtn.disabled = false;
  2938.             oF.batchBtn.className = "batchOn";
  2939.             oF.abortBtn.className = "abortOff";
  2940.             oF.encodeBtn.src="images/start_1.jpg";
  2941.         }
  2942.  
  2943.         /*
  2944.         if (batchProgress < 0 && pfso && window.AVSfile && (multi_num < 1 || multi_pass >= multi_num))
  2945.         {
  2946.             try
  2947.             {
  2948.                 //pfso.DeleteFile(AVSfile);
  2949.             }
  2950.             catch(e) {}
  2951.             //AVSfile=null;
  2952.         }
  2953.         */
  2954.  
  2955.         encodeShell=null;
  2956.         pfso=null;
  2957.  
  2958.         if (line != 'ERROR')
  2959.         {
  2960.             if (multi_num > 0 && multi_pass < multi_num)
  2961.             {
  2962.                 
  2963.                 multi_pass++;
  2964.                 ff.txtOut.value = "Preparing part "+ multi_pass +" ...";
  2965.                 encode(multi_pass);
  2966.                 return;
  2967.             }
  2968.             if (batchProgress < 0)
  2969.                 encodingComplete(hasAborted);
  2970.             else
  2971.                 encodeAll();
  2972.         }
  2973.         else
  2974.         {
  2975.             ff.txtOut.value = "Encoding Error.";
  2976.             da.progCanvas.style.visibility = "hidden";
  2977.             ff.recTime.value = "";
  2978.             startTm=null;
  2979.         }
  2980.     }
  2981.     else
  2982.         setTimeout("progress()", 500);
  2983. }
  2984.  
  2985. // Prepend with zeros to a certain precision
  2986. function formatZero(num, prec)
  2987. {
  2988.     var newN = ""+ num;
  2989.     var toAdd = prec - newN.length;
  2990.     if (toAdd > 0)
  2991.     {
  2992.         for(i=0; i<toAdd; i++)
  2993.             newN = "0"+ newN;
  2994.     }
  2995.     return newN;
  2996. }
  2997.  
  2998. // If this action is checked, we give a warning and shutdown the PC
  2999. function checkShutdown()
  3000. {
  3001.     if (oF.shutDown.checked)
  3002.     {
  3003.         ff.txtOut.value += "\nPreparing for Shutdown.";
  3004.         try
  3005.         {
  3006.             window.encodeShell = new ActiveXObject( "WScript.shell" );
  3007.             encodeShell.run( '%comspec% /c .\\shutdown.bat', 0, false);
  3008.             for(i=0;i<1000;i++);
  3009.             encodeShell=null;
  3010.          }
  3011.          catch(e)
  3012.          {
  3013.              alert("Error in shutdown procedure: "+ e.message);
  3014.          }
  3015.          return true;
  3016.     }
  3017.     return false;
  3018. }
  3019.  
  3020. // Estimate the output size based on total "fixed" bit rate
  3021. function estimateSize(obj)
  3022. {
  3023.     // Validate recStart and recEnd
  3024.     if (obj && obj.name == "recEnd" && parseInt(obj.value) > inTarget)
  3025.         obj.value = inTarget;
  3026.     else if (obj && obj.name == "recStart" && parseInt(obj.value) >= parseInt(oF.recEnd.value))
  3027.         obj.value = "0";
  3028.  
  3029.     var siz;
  3030.     var clipLength = parseInt(oF.recEnd.value) - parseInt(oF.recStart.value);
  3031.  
  3032.     if (obj && obj.name == "fixSize")
  3033.     {
  3034.         // When fixed size is used, we need to calculate the Video Bitrate
  3035.         siz = parseInt(obj.value) * 1024;
  3036.         var br = Math.floor((siz - 150) * 8 / clipLength);
  3037.         oF.vRate.value = br - parseInt(oF.aRate.value);
  3038.         oF.vRate.style.fontWeight = "bold";
  3039.         oF.fixSize.style.fontWeight = "normal";
  3040.     }
  3041.     else
  3042.     {    
  3043.         var br = parseInt(oF.vRate.value) + parseInt(oF.aRate.value);
  3044.         siz= Math.ceil(br/8 * clipLength + 150);
  3045.         oF.vRate.style.fontWeight = "normal";
  3046.         oF.fixSize.style.fontWeight = "bold";
  3047.     }
  3048.     
  3049.     if (oF.vRate.value >= 128 && siz > 1524)
  3050.     {
  3051.         siz = siz - Math.floor(siz/1524);
  3052.     }
  3053.  
  3054.     if (oF.fRate.value <20 && siz > 524)
  3055.     {
  3056.         siz = siz - Math.floor(siz/524)
  3057.     }
  3058.     
  3059.     if (siz < 1024)
  3060.         ff.outSize.value = siz +" KB";
  3061.     else
  3062.         ff.outSize.value = Math.ceil(siz/1024) +" MB";
  3063.  
  3064.     oF.fixSize.value = Math.ceil(siz/1024);
  3065.  
  3066.     if (oF.splitTo.value != "" && parseInt(oF.splitTo.value) >= parseInt(oF.fixSize.value))
  3067.         clearSplit();    // We can't keep the split settings if the size changed too low
  3068.  
  3069.     getOutDuration();
  3070. }
  3071.  
  3072. // Update the Output Duration
  3073. function getOutDuration()
  3074. {
  3075.     var dur, rem;
  3076.     var totSec = oF.recEnd.value - parseInt(oF.recStart.value);
  3077.     if (!isNaN(totSec))
  3078.     {
  3079.         dur = preZero(totSec % 60);
  3080.         rem = parseInt(totSec / 60);
  3081.         if (rem > 0)
  3082.         {
  3083.             dur = preZero(rem % 60) +":"+ dur;
  3084.             rem = parseInt(rem / 60);
  3085.             if (rem > 0)
  3086.                 dur = preZero(rem % 60) +":"+ dur;
  3087.             else
  3088.                 dur = "00:"+ dur;
  3089.         }
  3090.         else
  3091.             dur = "00:00:"+ dur;
  3092.  
  3093.         oF.outLength.value = dur;
  3094.     }
  3095. }
  3096.  
  3097. function setStartPos()
  3098. {
  3099.     if (!oF.recStart.readOnly)
  3100.         oF.recStart.value = shotPos;
  3101. }
  3102.  
  3103. function setEndPos()
  3104. {
  3105.     if (!oF.recEnd.readOnly)
  3106.         oF.recEnd.value = shotPos;
  3107. }
  3108.  
  3109. // Abort the encoding by sending a message via MediaCellEngine.fmm
  3110. // The resulting partial encoded file should still be viewable
  3111. function abort(isComplete)
  3112. {
  3113.     // Abort the Indexing
  3114.     if (window.duringIndex)
  3115.     {
  3116.         try
  3117.         {
  3118.             window.killShell = new ActiveXObject( "WScript.shell" );
  3119.             killShell.run( '%comspec% /c taskkill.exe /IM DGindex.exe > .\\kill.log 2>&1', 0, false );
  3120.                  for(i=0;i<1000;i++);
  3121.             killShell=null;
  3122.             ff.txtOut.value = "DVD Preparation Aborted.";
  3123.             window.indexAborted = true;
  3124.          }
  3125.          catch(e)
  3126.          {
  3127.              killShell=null;
  3128.              window.indexAborted = true;
  3129.              if (debugMode) alert("Error killing the DVD index process. "+ e.message);
  3130.          }
  3131.  
  3132.         indexComplete=false;
  3133.         da.progBar.style.backgroundColor = "red";
  3134.         oF.encodeBtn.disabled = false;
  3135.         oF.encodeBtn.className = "goOn";
  3136.         oF.batchBtn.disabled = false;
  3137.         oF.batchBtn.className = "batchOn";
  3138.         oF.abortBtn.blur();
  3139.         oF.abortBtn.className = "abortOff";
  3140.         oF.encodeBtn.src="images/start_1.jpg";
  3141.         indexShell=null;
  3142.         pfso=null;
  3143.         duringIndex=false;
  3144.         return;
  3145.     }
  3146.  
  3147.     // Abort the Subtitle Extraction
  3148.     if (window.duringSubt)
  3149.     {
  3150.         try
  3151.         {
  3152.             window.killShell = new ActiveXObject( "WScript.shell" );
  3153.             killShell.run( '%comspec% /c taskkill.exe /IM rundll32.exe /f > .\\kill.log 2>&1', 0, false );
  3154.                  for(i=0;i<1000;i++);
  3155.             killShell=null;
  3156.             ff.txtOut.value = "Subtitle Extraction Aborted.";
  3157.             window.subtAborted = true;
  3158.             window.vsCfg=null;
  3159.          }
  3160.          catch(e)
  3161.          {
  3162.              killShell=null;
  3163.              window.subtAborted = true;
  3164.              window.vsCfg=null;
  3165.              if (debugMode) alert("Error killing subtitle extract. "+ e.message);
  3166.          }
  3167.  
  3168.         da.progBar.style.backgroundColor = "red";
  3169.         oF.encodeBtn.disabled = false;
  3170.         oF.encodeBtn.className = "goOn";
  3171.         oF.batchBtn.disabled = false;
  3172.         oF.batchBtn.className = "batchOn";
  3173.         oF.abortBtn.blur();
  3174.         oF.abortBtn.className = "abortOff";
  3175.         oF.encodeBtn.src="images/start_1.jpg";
  3176.         window.subShell = null;
  3177.         pfso=null;
  3178.         duringSubt=false;
  3179.         return;
  3180.     }
  3181.  
  3182.     // Otherwise, abort the Encoding
  3183.     try
  3184.     {
  3185.         var fso = new ActiveXObject( "Scripting.Filesystemobject" );
  3186.         /*var fmm = fso.OpenTextFile('.\\MediaCellEngine.fmm',8);
  3187.         fmm.Write("Q\n");
  3188.         fmm.Close();
  3189.         fmm=null;
  3190.         fso=null;*/
  3191.     
  3192.         oF.encodeBtn.disabled = false;
  3193.         oF.encodeBtn.className = "goOn";
  3194.         oF.batchBtn.disabled = false;
  3195.         oF.batchBtn.className = "batchOn";
  3196.         oF.abortBtn.blur();
  3197.         oF.abortBtn.className = "abortOff";
  3198.         oF.encodeBtn.src="images/start_1.jpg";
  3199.     
  3200.         if (isComplete)
  3201.         {
  3202.             // Implicit abort happens because we reached the user-selected End position
  3203.             encodeShell=null;
  3204.             pfso=null;
  3205.             encodingComplete();
  3206.         }
  3207.         else
  3208.         {
  3209.             // User-explicit abort
  3210.             oF.shutDown.checked = false;
  3211.             ff.txtOut.value = "Encoding Aborted.";
  3212.             da.progBar.style.backgroundColor = "red";
  3213.             da.instLink.style.visibility = "visible";
  3214.             encodeShell=null;
  3215.             pfso=null;
  3216.             alert("Encoding aborted.\n\nNote: In most cases, the partially encoded file\nis still viewable in a media player.");
  3217.         }
  3218.         batchProgress = -1;
  3219.     }
  3220.     catch(e)
  3221.     {
  3222.         alert("Error aborting the encoding: "+ e.message);
  3223.     }
  3224. }
  3225.  
  3226. function encodingComplete(hasAborted)
  3227. {
  3228.     if (!hasAborted)
  3229.         ff.txtOut.value = "Encoding Complete.";
  3230.     da.progCanvas.style.visibility = "hidden";
  3231.     da.instLink.style.visibility = "visible";
  3232.     ff.recTime.value = "";
  3233.     startTm=null;
  3234.     batchProgress = -1;
  3235.  
  3236.     if (!hasAborted && !checkShutdown())
  3237.         showInstall();
  3238. }
  3239.  
  3240. function openOutFolder()
  3241. {
  3242.         try
  3243.         {
  3244.             // Try to open Explorer in the output folder
  3245.             window.encodeShell = new ActiveXObject( "WScript.shell" );
  3246.             encodeShell.run( 'explorer.exe "'+ outPath +'"' );
  3247.             window.encodeShell = null;
  3248.         }
  3249.     catch(e) { window.encodeShell=null; showInstall(); }
  3250. }
  3251.  
  3252. function toggleCropping()
  3253. {
  3254.     cropPreset++;
  3255.     optimize(true);
  3256. }
  3257.  
  3258. function cleanTitle(ttl)
  3259. {
  3260.     var par1 = ttl.search(/\(/);
  3261.     var par2 = ttl.search(/\)/);
  3262.     if (par1 > 0 && par2 > 0 && par1 < par2)
  3263.         ttl = ttl.substr(0,par1).replace(/\s+$/,"");
  3264.  
  3265.     return ttl.replace(/_/g, ' ');
  3266. }
  3267.  
  3268. function updateOutPath()
  3269. {
  3270.     da.instLink.style.visibility = "hidden";
  3271.     var t = oF.fName.value.match(/^(.*)\\([^\\]+)$/);
  3272.     if (t)
  3273.     {
  3274.         outPath = t[1];
  3275.         outTitle = cleanTitle(t[2].replace(/\.[a-zA-Z0-9]+$/i,'').replace(/_M$/,''));
  3276.     }
  3277. }
  3278.  
  3279. function saveVemodeSettings()
  3280. {
  3281.     window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  3282.     var cf = pfso.Opentextfile("vemode.cfg", 2, true, 0);  // Writing - Create if needed - ASCII
  3283.     cf.WriteLine('lastDevice="'+ oF.device.value +'";\n'
  3284.             +'lastVMRun="'+ VMHta.version +'";\n'
  3285.             +'defaultOutPath="'+ defaultOutPath.replace(/\\/g,"\\\\") +'";\n'
  3286.             +'debugMode='+ debugMode +';\n'
  3287.             +'VMMode="'+ VMMode +'";');
  3288.     cf.close();
  3289.     psfo=null;
  3290. }
  3291.  
  3292. function loadVemodeSettings()
  3293. {
  3294.     try
  3295.     {
  3296.         window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  3297.  
  3298.         if (!pfso.FileExists( "vemode.cfg" ))
  3299.         {
  3300.             window.isFirstEverRun=true;
  3301.             pfso=null;
  3302.             return;
  3303.         }
  3304.  
  3305.         var cf = pfso.Opentextfile("vemode.cfg");
  3306.         var line;
  3307.         while (cf && !cf.atEndOfStream)
  3308.         {
  3309.             line = cf.ReadLine();
  3310.             if (line)
  3311.                 eval(line);
  3312.         }
  3313.         cf.close();
  3314.     }
  3315.     catch(e) 
  3316.     {
  3317.         if (debugMode) alert("Error loading MediaCell Settings. "+ e.message);
  3318.     }
  3319.     psfo=null;
  3320. }
  3321.  
  3322. // Toggle Easy / Advanced Modes
  3323. function toggleVMMode(init)
  3324. {
  3325.     if (!init)
  3326.     {
  3327.         VMMode = (VMMode == 'EZ') ? 'ADVANCED' : 'EZ';
  3328.         saveVemodeSettings();
  3329.     }
  3330.     else if (window.isFirstEverRun)
  3331.         VMMode = 'EZ';
  3332.  
  3333.     var EZ = (VMMode == 'EZ');
  3334.  
  3335.     da.ezLink.innerHTML = (EZ) ? da.ezLink.innerHTML.replace(/Disable/,"Enable")
  3336.                    : da.ezLink.innerHTML.replace(/Enable/,"Disable");
  3337.     oF.saveBtn.style.visibility = (EZ) ? "hidden" : "visible";
  3338.     oF.splitBtn.style.visibility = (EZ) ? "hidden" : "visible";
  3339.     oF.batchBtn.style.visibility = (EZ) ? "hidden" : "visible";
  3340.     da.formatRow.style.visibility = (EZ) ? "hidden" : "visible";
  3341.     for (i=2; i <= 6; i++)
  3342.         eval("da.optRow"+ i).style.visibility = (EZ) ? "hidden" : "visible";
  3343.  
  3344.     //ezMessage(EZ);
  3345. }
  3346.  
  3347. // Display Install instructions for the output video
  3348. function showInstall()
  3349. {
  3350.     // Get the output file info
  3351.     var oFN="", oFE="";
  3352.     var m = oF.fName.value.match(/^(.*)\\(.+)\.([a-zA-Z0-9]+)$/);
  3353.     if (m)
  3354.     {
  3355.         oFN = m[2] +'.'+ m[3];
  3356.         oFE = m[3];
  3357.     }
  3358.  
  3359.     var avSp = (oF.splitTo.value) ? ('at least <b>'+ oF.splitTo.value +' MB</b> of ') : ((ff.outSize.value && multi_num < 1) ? ('at least <b>'+ ff.outSize.value +'</b> of ') : 'enough');
  3360.  
  3361.     var html = '<table bgcolor="#ABC0D5" cellpadding=5 cellspacing=0><tr><td>'
  3362.         +'<H4>Installing the video on your '+ currDevLabel +'</H4>';
  3363.  
  3364.     if (batchQ && numInQ > 0)
  3365.         html += '<B style="color:red">NOTE: When converting multiple files in a queue, '
  3366.             +'the window below shows the folder where the last encoded video was saved.</B>';
  3367.  
  3368.     if (currDevName == 'IPOD')
  3369.     {
  3370.        html += '<OL><LI>Launch iTunes on your PC.'
  3371.         +'<LI>Drag the '+ ((multi_num > 0) ? '<b>.'+ oFE +'</b> files' : '"<b>'+ oFN +'</b>" file') 
  3372.         +' from the box below and drop '+ ((multi_num > 0) ? 'them' : 'it') +' into the iTunes window.'
  3373.         +'<LI>Connect your '+ currDevLabel +'.'
  3374.         +'</OL>'
  3375.         +'<table border=0 cellpadding=0 cellspacing=2 bgcolor="#ABC0D5"><tr><td>'
  3376.         +'<IFRAME id="exWin" SRC="'+ outPath +'" TITLE="Output Folder" border=1 width="500" height="200"><\/IFRAME></td></tr></table>'
  3377.         +'<br><center>[<a href="#" onclick="closeMessage(\'vinst\')">Close</a>]</center></td></tr></table>';
  3378.     }
  3379.     else if (currDevName == 'PSP')
  3380.     {
  3381.        html += '<OL><LI>Make sure you have a Memory Stick with '+ avSp +' free space.'
  3382.            +'<LI>Connect your '+ currDevLabel +' to a USB port on your PC.'
  3383.            +'<LI>Open the connection from your PSP by going to HOME, then SETTINGS, then "USB CONNECTION".'
  3384.            +'<LI>This should open a window showing the root folder of your memory stick.'
  3385.         +'<LI>From that window, go to the <b>MP_ROOT</b> folder, then the <b>100MNV01</b> folder. If these folders don\'t exist, create them and make sure the 100MNV01 folder is inside the MP_ROOT folder.'
  3386.         +'<LI>Drag '+ ((multi_num > 0) ? 'the desired <b>.'+ oFE +'</b> and <b>.THM</b> files' : 'both the "<b>'+ oFN +'</b>" and the "<b>'+ oFN.replace(/\.[0-9a-zA-Z]+$/,".THM") +'</b>" files') 
  3387.         +' from the box below and drop them onto the <b>100MNV01</b> folder within your Memory Stick.'
  3388.         +'</OL>'
  3389.         +'<table border=0 cellpadding=0 cellspacing=2 bgcolor="#ABC0D5"><tr><td>'
  3390.         +'<IFRAME id="exWin" SRC="'+ outPath +'" TITLE="Output Folder" border=1 width="500" height="150"><\/IFRAME></td></tr></table>'
  3391.         +'<br><center>[<a href="#" onclick="closeMessage(\'vinst\')">Close</a>]</center></td></tr></table>';
  3392.     }
  3393.     else
  3394.     {
  3395.        html += '<OL><LI>Connect your '+ currDevLabel +' or a card reader to your PC so that you can access the memory card.'
  3396.         +'<LI>Open the folder within the memory card where you wish to install the video files.'
  3397.         +'<LI>Ensure that there is '+ avSp +' free space on your memory card.'    
  3398.         +'<LI>Drag the '+ ((multi_num > 0) ? 'desired <b>.'+ oFE +'</b> files' : '"<b>'+ oFN +'</b>" file')
  3399.         +' from the box below and drop '+ ((multi_num > 0) ? 'them' : 'it') +' onto the folder within your memory card.'
  3400.         +'</OL>'
  3401.         +'<table border=0 cellpadding=0 cellspacing=2 bgcolor="#ABC0D5"><tr><td>'
  3402.         +'<IFRAME id="exWin" SRC="'+ outPath +'" TITLE="Output Folder" border=1 width="500" height="200"><\/IFRAME></td></tr></table>'
  3403.         +'<br><center>[<a href="#" onclick="closeMessage(\'vinst\')">Close</a>]</center></td></tr></table>';
  3404.     }
  3405.  
  3406. //    if (document.Player1.enabled)
  3407. //    {
  3408. //        toggleActive(document.Player1);
  3409. //        window.enablePreviewOnClose=true;
  3410. //    }
  3411.     popMessageInstall('vinst',html,true, 60, 30);
  3412. }
  3413.  
  3414. function forceModalWindow(win)
  3415. {
  3416.     if (win && !win.closed)
  3417.     {
  3418.         win.blur();
  3419.         window.focus();
  3420.         win.focus();
  3421.     }
  3422. }
  3423.  
  3424. function init()
  3425. {
  3426.     window.ff = document.fF;
  3427.     window.f = document.vF;
  3428.     window.oF = document.oF;
  3429.     window.da = document.all;
  3430.  
  3431.     window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  3432.     if (pfso.FileExists("activate.exe"))
  3433.     {
  3434.         window.encodeShell = new ActiveXObject( "WScript.shell" );
  3435.         encodeShell.run( '%comspec% /c .\\activate.exe', 0, true );
  3436.         window.outStream=null;
  3437.  
  3438.         pfso.DeleteFile("activate.exe");
  3439.     }
  3440.  
  3441.     if (pfso.FileExists("MediaCell Auto Update.exe"))
  3442.     {
  3443.         window.encodeShell = new ActiveXObject( "WScript.shell" );
  3444.         encodeShell.run( '%comspec% /c ".\\MediaCell Auto Update.exe"', 0, true );
  3445.         window.outStream=null;
  3446.     }
  3447.     
  3448.     da.cropArrows.style.top = da.cropArrows.offsetTop - 8;
  3449.  
  3450.     loadVemodeSettings();
  3451.     getConfig();
  3452.     toggleVMMode(true);
  3453.  
  3454.     for (var i=0; i < devices.length; i++)
  3455.     {
  3456.         oF.device.options[oF.device.options.length] = new Option(devices[i].label,devices[i].name);
  3457.         if (lastDevice && devices[i].name == lastDevice)
  3458.             oF.device.selectedIndex = i;
  3459.     }
  3460.     ssSyncOptions(oF.device);
  3461.  
  3462.     // Check if we support de-activating the preview
  3463.     //var ver = (document.Player1 && document.Player1.versionInfo) ? parseInt(document.Player1.versionInfo.substr(0,document.Player1.versionInfo.search(/\./))) : 0;
  3464.     //if (ver < 9)
  3465.     //    fF.usePreview.style.visibility = "hidden";
  3466.  
  3467.     optimize();
  3468.  
  3469. //    document.currentMenu=fileMenu;
  3470.     localPath = appPath.substr(1,appPath.length-3).replace(/\\[a-zA-Z\.]+$/,'');
  3471. }
  3472.  
  3473. function changeDeviceRes(obj)
  3474. {
  3475.     if (!devices) getConfig(); // Retrieve the device configs
  3476.     mdWidth = devices[currDevice].pixelWidth = parseInt(obj.value.substr(0,obj.value.search('x')));
  3477.     mdHeight= devices[currDevice].pixelHeight= parseInt(obj.value.substr(obj.value.search('x')+1));
  3478.     optimize();
  3479. }
  3480.  
  3481. function onDrop()
  3482. {
  3483.     scanFile()
  3484. }
  3485.  
  3486. /*function ezMessage(isOn)
  3487. {
  3488.     if (!da.ezMsg) return;
  3489.  
  3490.     if (!isOn)
  3491.     {
  3492.         da.ezMsg.style.visibility = "hidden";
  3493.         return;
  3494.     }
  3495.  
  3496. //    var msg = '<B style="font:bold 9pt">How to MediaCell</B><BR><BR>'
  3497. //        +' <B>1.</B> Select a <b>Video File to Convert</b> by clicking the "<b>Browse...</b>" button above.<br>'
  3498. //        +' <B>2.</B> Select a device from the <b>Optimize for Device</b> list above.<br>'
  3499. //        +' <B>3.</B> Click the <b>Encode Video!</b> button below.<br><br>'
  3500. //        +'<i>When the encoding is finished you will be presented with further instructions to transfer the new video onto your device.</i>';
  3501.  
  3502.     //da.ezMsg.style.color = "#000055";
  3503.     //da.ezMsg.style.backgroundImage = "url(images/bgrad.png)";
  3504.     //da.ezMsg.style.left = 30;
  3505.     //da.ezMsg.style.top  = da.mdImage.offsetParent.offsetParent.offsetTop + 20;
  3506.     //da.ezMsg.style.width = 400;
  3507.     //da.ezMsg.innerHTML = msg;
  3508.     //da.ezMsg.style.height = da.ezMsg.scrollHeight;
  3509.     da.ezMsg.style.visibility = "hidden";
  3510. }*/
  3511.  
  3512. function popMessageAbout(name, msg, skipTimeout, optX, optY)
  3513. {
  3514.     if (!da.popMsg || da.popMsg.style.visibility == "visible")
  3515.         return;
  3516.  
  3517.     da.popMsg.lastName = name;
  3518.     var e = window.event;
  3519.     
  3520.     da.popMsg.style.backgroundColor = "#FFFFFF";
  3521.     //da.popMsg.style.left = (!optX) ? e.clientX : optX;
  3522.     da.popMsg.style.left = 515;
  3523.     da.popMsg.innerHTML = msg;
  3524.     da.popMsg.style.height = da.popMsg.scrollHeight;
  3525.     
  3526.     //if (!optY && (e.clientY + da.popMsg.scrollHeight > 550))
  3527.     //    da.popMsg.style.top = e.clientY - da.popMsg.scrollHeight - 10;
  3528.     //else
  3529.     //    da.popMsg.style.top =((!optY) ? e.clientY : optY);
  3530.     da.popMsg.style.top =-220;
  3531.     da.popMsg.style.visibility = "visible";
  3532.     if (!skipTimeout)
  3533.         pmTimer = setTimeout("closeMessage('"+ name +"')", 15000);
  3534.         
  3535. }
  3536.  
  3537. function popMessageSplit(name, msg, skipTimeout, optX, optY)
  3538. {
  3539.     if (!da.popMsg || da.popMsg.style.visibility == "visible")
  3540.         return;
  3541.  
  3542.     da.popMsg.lastName = name;
  3543.     var e = window.event;
  3544.     da.popMsg.style.backgroundColor = "#FFFFFF";
  3545.     //da.popMsg.style.left = (!optX) ? e.clientX : optX;
  3546.     da.popMsg.style.left = 505;
  3547.     da.popMsg.innerHTML = msg;
  3548.     da.popMsg.style.height = da.popMsg.scrollHeight;
  3549.     //if (!optY && (e.clientY + da.popMsg.scrollHeight > 550))
  3550.     //    da.popMsg.style.top = e.clientY - da.popMsg.scrollHeight - 10;
  3551.     //else
  3552.     //    da.popMsg.style.top =((!optY) ? e.clientY : optY);
  3553.     da.popMsg.style.top =120;
  3554.     da.popMsg.style.visibility = "visible";
  3555.  
  3556.     if (!skipTimeout)
  3557.         pmTimer = setTimeout("closeMessage('"+ name +"')", 15000);
  3558. }
  3559.  
  3560. function popMessageInstall(name, msg, skipTimeout, optX, optY)
  3561. {
  3562.     if (!da.popMsg || da.popMsg.style.visibility == "visible")
  3563.         return;
  3564.  
  3565.     da.popMsg.lastName = name;
  3566.     var e = window.event;
  3567.     da.popMsg.style.backgroundColor = "#FFFFFF";
  3568.     //da.popMsg.style.left = (!optX) ? e.clientX : optX;
  3569.     da.popMsg.style.left = 100;
  3570.     da.popMsg.innerHTML = msg;
  3571.     da.popMsg.style.height = da.popMsg.scrollHeight;
  3572.     //if (!optY && (e.clientY + da.popMsg.scrollHeight > 550))
  3573.     //    da.popMsg.style.top = e.clientY - da.popMsg.scrollHeight - 10;
  3574.     //else
  3575.     //    da.popMsg.style.top =((!optY) ? e.clientY : optY);
  3576.     da.popMsg.style.top =-200;
  3577.     da.popMsg.style.visibility = "visible";
  3578.  
  3579.     if (!skipTimeout)
  3580.         pmTimer = setTimeout("closeMessage('"+ name +"')", 15000);
  3581. }
  3582.  
  3583. function closeMessage(name, skipTogglePreview)
  3584. {
  3585.     if (!da.popMsg || da.popMsg.lastName != name)
  3586.         return;
  3587.  
  3588.     if (pmTimer) clearTimeout(pmTimer);
  3589.     pmTimer = null;
  3590.     da.popMsg.style.visibility = "hidden";
  3591.  
  3592. //    if ((name == 'vinst' || name == 'pBatch') && !skipTogglePreview)
  3593. //    {
  3594. //        if(window.enablePreviewOnClose)
  3595. //            toggleActive(document.Player1);
  3596. //        window.enablePreviewOnClose=false;
  3597. //    }
  3598. }
  3599.  
  3600. function splitVideo()
  3601. {
  3602.     if (fileInput == "")
  3603.         return;
  3604.  
  3605.     var msg = '<B>Split into smaller parts</B><br><br>'
  3606.             +'This will split the encoded video into parts of a specified size. This is useful if the movie doesn\'t fit in your memory cards and you want to keep the quality high.<br><br>'
  3607.             +'<b>Size of parts</b>:<input id="splitSel" size=6 value="'+ oF.splitTo.value +'"> MB   <input type="button" value="OK" onclick="setSplit()">  <input type="button" value="Clear" onclick="clearSplit()"><br><br>'
  3608.             +'<center>[<a href="#" onclick="closeMessage(\'split\')">Close</a>]</center>';
  3609.             
  3610.     popMessageSplit('split',msg, true);
  3611. }
  3612.  
  3613. function AboutMsg()
  3614. {
  3615.     var msg = '<B>MediaCell Mobile Video Converter v2.55</B><br><br>'
  3616.             +'Copyright ⌐ 2006-2007 MediaCell<br>All Rights Reserved<br><br>'
  3617.             +'<b>MediaCell contact is:  </b><a href="mailto:info@media-cell.com" target="_blank">info@media-cell.com</a><br>'
  3618.             +'<b>Website:  </b><a href="http://www.media-cell.com" target="_blank">www.media-cell.com</a><br><br>'
  3619.             +'<center>[<a href="#" onclick="closeMessage(\'about\')">Close</a>]</center>';
  3620.             
  3621.     popMessageAbout('about',msg, true);
  3622. }
  3623.  
  3624. function setSplit()
  3625. {
  3626.     if (isNaN(da.splitSel.value) || parseInt(da.splitSel.value) >= parseInt(oF.fixSize.value))
  3627.     {
  3628.         da.splitSel.select();
  3629.         return;
  3630.     }
  3631.  
  3632.     oF.splitTo.value = da.splitSel.value;
  3633.     closeMessage('split');
  3634.     oF.splitBtn.className = "yellowBtn";
  3635. }
  3636.  
  3637. function clearSplit()
  3638. {
  3639.     if (oF)
  3640.     {
  3641.         oF.splitTo.value = "";
  3642.         closeMessage('split');
  3643.         oF.splitBtn.className = "greenBtn";
  3644.     }
  3645. }
  3646.  
  3647. function grabSubtitles(batchAction)
  3648. {
  3649.     //if (!confirm("The system will now extract the subtitles to prepare them for the conversion.\n\n"
  3650.     //    +"This will take a few minutes. Click OK to start."))
  3651.     //    return;
  3652.  
  3653.     if (isMultiVOB)
  3654.     {
  3655.         // Generate the config file for VobSub
  3656.         var slang = f.subt.value;
  3657.  
  3658.         window.AVSfile = null;
  3659.         if (!window.secOutPath)
  3660.             setSecondaryOutPath();
  3661.  
  3662.         try
  3663.         {
  3664.             window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  3665.             window.vsCfg = secOutPath +"\\vobsub";  // Default Name
  3666.             var m = oF.fName.value.match(/\\([^.\\]+)\.[^.]+$/);
  3667.             if (m)
  3668.             {
  3669.                 vsCfg = secOutPath +"\\"+ m[1] +"_"+ slang;  // Preferred Name
  3670.     
  3671.                 // If the sub files already exist, we can skip the extraction
  3672.                 if (!window.subtAborted && pfso.FileExists( vsCfg +".sub" ) && pfso.FileExists( vsCfg +".idx" ))
  3673.                 {
  3674.                     window.lastSubCmd=null;
  3675.                     pfso=null;
  3676.                     subOffset();
  3677.                     if (!batchAction && window.nextDone == "SUB")
  3678.                     {
  3679.                         encodeAll("SUB");  // Return to where we were in the Batch encoding
  3680.                         return;
  3681.                     }
  3682.                     if (!batchAction) indexDVD();  // Resume where we left off
  3683.                     return;
  3684.                 }
  3685.             }
  3686.  
  3687.             var cf = pfso.CreateTextFile(vsCfg +".cfg", true);  // Overwrite if needed
  3688.             cf.WriteLine(ifoFile);
  3689.             cf.WriteLine(vsCfg);
  3690.             cf.WriteLine('1');
  3691.             cf.WriteLine('0');  // TODO: Get the right PCG?
  3692.             cf.WriteLine(slang);
  3693.             cf.WriteLine('CLOSE');
  3694.             cf.close();
  3695.             psfo=null;
  3696.         }
  3697.         catch(e)
  3698.         {
  3699.             psfo=null;
  3700.              alert("Sub Extraction: "+ e.message);
  3701.         }
  3702.  
  3703.         window.lastSubCmd = '%comspec% /c rundll32 .\\Vobsub\\vobsub.dll,Configure '+ vsCfg +'.cfg > .\\vobsub.log 2>&1';
  3704.  
  3705.         if (batchAction == "ADD")
  3706.             return;
  3707.  
  3708.         // Run VobSub
  3709.         try
  3710.         {
  3711.             window.subtAborted=null;
  3712.             window.vsShell = new ActiveXObject( "WScript.shell" );
  3713.             vsShell.run(lastSubCmd, 0, false );
  3714.             
  3715.             /*
  3716.             // TODO: Support monitoring of the .SUB file progress (IDX is created at the end only)
  3717.             
  3718.             // For now, we just go back to where we were and allow the rest of the processing to occur
  3719.             for(i=0;i<10000;i++);
  3720.             if (window.nextDone == "SUB")
  3721.             {
  3722.                 encodeAll("SUB");  // Return to where we were in the Batch encoding
  3723.                 return;
  3724.             }
  3725.             // Can't subOffset until we have an IDX file, so the first time the offset is not supported
  3726.             //subOffset();
  3727.             indexDVD();  // Resume where we left off
  3728.             return;
  3729.             */
  3730.  
  3731.             window.outStream=null;
  3732.             window.duringSubt = true;
  3733.          }
  3734.          catch(e)
  3735.          {
  3736.             window.vsShell = null;
  3737.              alert("Subtitle Extract Error: "+ e.message);
  3738.              return;
  3739.          }
  3740.     
  3741.         // Start tracking progress on the indexing
  3742.         ff.txtOut.value = "Extracting Subtitles from DVD...";
  3743.         oF.encodeBtn.disabled = true;
  3744.         oF.encodeBtn.className = "goOff";
  3745.         oF.abortBtn.className = "abortOn";
  3746.         oF.encodeBtn.src="images/start_on.jpg";
  3747.         oF.batchBtn.disabled = true;
  3748.         oF.batchBtn.className = "goOff";
  3749.         window.lastSPos=null;
  3750.  
  3751.         setTimeout("subtProgress(1)", 1000);
  3752.     }
  3753. }
  3754.  
  3755. // Track progress of the indexing
  3756. function subtProgress(isStart)
  3757. {
  3758.     var hasAborted = (ff.txtOut.value.search(/Subtitle Extraction Aborted/i) == 0);
  3759.  
  3760.     if (!window.outStream)
  3761.     {
  3762.         window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  3763.         if (!pfso.FileExists(vsCfg +".idx"))
  3764.         {
  3765.             pfso=null;
  3766.             if (window.subtAborted || hasAborted) return;
  3767.  
  3768.             // Check regularly until we find an IDX file to scan
  3769.             setTimeout("subtProgress()", 2000);
  3770.             return;
  3771.         }
  3772.         window.outStream = pfso.OpenTextFile(vsCfg +".idx");
  3773.     }
  3774.     var m, pos, line = String();
  3775.     var atEnd = outStream.atEndOfStream;
  3776.     if( !atEnd && (line = outStream.Read(4000)) )
  3777.     {
  3778.         if (isStart && line.search(/^\# VobSub/) < 0)
  3779.         {
  3780.             if (isStart > 5)
  3781.             {
  3782.                 alert("Error:\n\n"+ line);
  3783.                 oF.encodeBtn.disabled = false;
  3784.                 oF.encodeBtn.className = "goOn";
  3785.                 oF.batchBtn.disabled = false;
  3786.                 oF.batchBtn.className = "batchOn";
  3787.                 oF.abortBtn.blur();
  3788.                 oF.abortBtn.className = "abortOff";
  3789.                 oF.encodeBtn.src="images/start_1.jpg";
  3790.                 ff.txtOut.value = 'Subtitle Extraction Aborted.';
  3791.                 return;
  3792.             }
  3793.  
  3794.             // Give it a second and try again
  3795.             setTimeout("subtProgress("+ (isStart+1) +")", 1000);
  3796.         }
  3797.  
  3798.         line = line.replace(/[\r\n]/g,"@");
  3799.  
  3800.         m = line.match(/@timestamp: (\d+):(\d+):(\d+):\d+,[^@]+@*$/);
  3801.         if (m)
  3802.         {
  3803.             var secDone = parseInt(m[1])*60*60 + parseInt(m[2])*60 + parseInt(m[3]);
  3804.  
  3805.             pos = secDone / recDuration * 100;
  3806.             if (pos > 100) pos = 100;
  3807.             if (pos < 1) pos = 1;
  3808.             if (window.lastSPos && pos < lastSPos) pos = lastSPos;
  3809.  
  3810.             if (!hasAborted)
  3811.                 ff.txtOut.value = "Extracting Subtitles ... " + Math.round(pos) +"%";
  3812.  
  3813.             da.progBar.style.width = Math.round(pos) +"%";
  3814.  
  3815.             if (startTm)
  3816.             {
  3817.                 encTimer = new Date();
  3818.                 var elapsed = (encTimer.getTime() - startTm);
  3819.                 var remains = Math.round(elapsed * 100 / pos) - elapsed;
  3820.                 var showSec = ((remains/60000) < 10); // Show seconds only when 10 minutes or less remain
  3821.  
  3822.                 if ((elapsed - lastElapsed) > 500)
  3823.                 {
  3824.                     lastElapsed = elapsed;
  3825.                     var elF = formatZero(Math.floor(remains / 3600000),2); // 1000ms * 60sec * 60min
  3826.                     remains -= Math.floor(remains / 3600000) * 3600000;
  3827.                     elF += ":"+ formatZero(Math.floor(remains / 60000),2);  // 1000ms * 60sec
  3828.                     remains -= Math.floor(remains / 60000) * 60000;
  3829.                     if (showSec)
  3830.                         elF += ":"+ formatZero(Math.floor(remains / 1000),2);
  3831.                     else
  3832.                         elF += ":00";
  3833.                     ff.recTime.value = elF;
  3834.                     encTimer = null;
  3835.                 }
  3836.             }
  3837.             m=null;
  3838.             window.lastSPos = pos;
  3839.         }
  3840.     }
  3841.  
  3842.     if (isStart)
  3843.     {
  3844.         ff.txtOut.value = "Extracting Subtitles ...";
  3845.         da.progCanvas.style.visibility = "visible";
  3846.         da.progBar.style.width = "0%";
  3847.         da.progBar.style.backgroundColor = "#FFA000";
  3848.         encTimer = new Date();
  3849.         startTm = encTimer.getTime();
  3850.         encTimer = null;
  3851.         lastElapsed = 0;
  3852.     }
  3853.  
  3854.     if (line && ((window.lastSPos && line.search(/@@@@$/) >= 0) || line=="ERROR" || hasAborted))
  3855.     {
  3856.         if (!hasAborted)
  3857.         {
  3858.             oF.encodeBtn.disabled = false;
  3859.             oF.encodeBtn.className = "goOn";
  3860.             oF.batchBtn.disabled = false;
  3861.             oF.batchBtn.className = "batchOn";
  3862.             oF.abortBtn.className = "abortOff";
  3863.             oF.encodeBtn.src="images/start_1.jpg";
  3864.         }
  3865.         vsShell=null;
  3866.         pfso=null;
  3867.  
  3868.         if (line != 'ERROR')
  3869.         {
  3870.             ff.txtOut.value = "";
  3871.             da.progCanvas.style.visibility = "hidden";
  3872.             ff.recTime.value = "";
  3873.             startTm=null;
  3874.             window.duringSubt = false;
  3875.             if (!hasAborted && window.nextDone == "SUB")
  3876.             {
  3877.                 encodeAll("SUB");  // Return to where we were in the Batch encoding
  3878.                 return;
  3879.             }
  3880.             if (!hasAborted)
  3881.             {
  3882.                 subOffset();
  3883.                 indexDVD();  // Resume where we left off
  3884.             }
  3885.         }
  3886.         else
  3887.         {
  3888.             ff.txtOut.value = "Indexing Error.";
  3889.             da.progCanvas.style.visibility = "hidden";
  3890.             ff.recTime.value = "";
  3891.             startTm=null;
  3892.             window.duringSubt = false;
  3893.         }
  3894.         window.nextDone=null;
  3895.     }
  3896.     else
  3897.         setTimeout("subtProgress()", 500);
  3898. }
  3899.  
  3900. // As needed apply an offset in seconds to the subtitles
  3901. function subOffset()
  3902. {
  3903.     if (f.subo.value == "" || isNaN(f.subo.value) || parseInt(f.subo.value)==0 || !window.vsCfg)
  3904.         return;
  3905.  
  3906.     var of=null, cf=null, m;
  3907.     try
  3908.     {
  3909.         window.pfso = new ActiveXObject( "Scripting.Filesystemobject" );
  3910.         if (!pfso.FileExists( vsCfg +".idx" ))
  3911.         {
  3912.             pfso=null;
  3913.             return;
  3914.         }
  3915.  
  3916.         // Make sure we have a backup of the original IDX file so we can let the user play with the offset many times
  3917.         var origSubIdx = vsCfg +".bidx";
  3918.         if (!pfso.FileExists( origSubIdx ))
  3919.             pfso.CopyFile(vsCfg +".idx", origSubIdx);
  3920.  
  3921.         of = pfso.Opentextfile(vsCfg +".idx", 2, true, 0);  // Writing - Create if needed - ASCII
  3922.         cf = pfso.Opentextfile(origSubIdx);
  3923.         var line;
  3924.         if (!cf || cf.atEndOfStream)
  3925.         {
  3926.             alert('Missing "'+ vsCfg +'.oidx" file');
  3927.             of.close();
  3928.             of=null;
  3929.             psfo=null;
  3930.             return;
  3931.         }
  3932.         var newTS, secs;
  3933.         while( !cf.atEndOfStream )
  3934.         {
  3935.             line = cf.ReadLine();
  3936.             m = line.match(/^timestamp: (\d+):(\d+):(\d+):(\d+,.+)$/);
  3937.             if (m)
  3938.             {
  3939.                 secs = parseInt(m[1])*60*60 + parseInt(m[2])*60 + parseInt(m[3]);
  3940.  
  3941.                 secs += parseInt(f.subo.value);  // Apply Offset
  3942.  
  3943.                 newTS = formatZero(Math.floor(secs / 3600),2);
  3944.                 secs -= Math.floor(secs / 3600) * 3600;
  3945.                 newTS += ":"+ formatZero(Math.floor(secs / 60),2);
  3946.                 secs -= Math.floor(secs / 60) * 60;
  3947.                 newTS += ":"+ formatZero(Math.floor(secs),2);
  3948.                 of.WriteLine("timestamp: "+ newTS +":"+ m[4]);
  3949.             }
  3950.             else
  3951.                 of.WriteLine(line);
  3952.         }        
  3953.         of.close();
  3954.         cf.close();
  3955.     
  3956.     }
  3957.     catch(e)
  3958.     {
  3959.         if (of && of.close) of.close();
  3960.         if (cf && cf.close) cf.close();
  3961.         pfso = null;
  3962.          alert("Subtitle Offset Error: "+ e.message);
  3963.     }
  3964. }
  3965.  
  3966. function showSubOffset()
  3967. {
  3968.     if (isMultiVOB)
  3969.     {
  3970.         // Make sure we will grab new subtitles and a different AVS file
  3971.         window.AVSfile = null;
  3972.         window.vsCfg = null;
  3973.     }
  3974.  
  3975.     if (f.subt.value != "")
  3976.     {
  3977.         document.getElementById("suboLbl").style.visibility = "visible";
  3978.         document.getElementById("suboFld").style.visibility = "visible";
  3979.         f.subo.value = "0";
  3980.     }
  3981.     else
  3982.     {
  3983.         document.getElementById("suboLbl").style.visibility = "hidden";
  3984.         document.getElementById("suboFld").style.visibility = "hidden";
  3985.     }
  3986. }
  3987. </script>
  3988. <script language="VBScript">
  3989. ' Ask for Yes No answer om a pop-up.
  3990. Function askYesNo(msg)
  3991.     askYesNo = MsgBox(msg, vbYesNo)
  3992. End Function
  3993.  
  3994. Function askYesNoCancel(msg)
  3995.     askYesNoCancel = MsgBox(msg, vbYesNoCancel)
  3996. End Function
  3997.  
  3998. Function okMessage(msg)
  3999.     okMessage = MsgBox(msg, vbOk)
  4000. End Function
  4001. </script>
  4002. <style type="text/css">
  4003. BODY    { FONT: 9pt Arial, Helvetica; color: DarkBlue; }
  4004. TD        { FONT: 9pt Arial, Helvetica; color: DarkBlue;}
  4005. TH        { FONT: bold 9pt Arial, Helvetica; color: DarkBlue;}
  4006. INPUT    { FONT: 8pt Verdana, Courier, Helvetica; background-color: #ABC0D5; color: DarkBlue;}
  4007. SELECT    { FONT: 8pt Verdana, Courier, Helvetica bold; color: DarkBlue; background-color: #ABC0D5;}
  4008. TEXTAREA { FONT: 8pt Verdana, Courier, Helvetica; color: DarkBlue; }
  4009. A            { color: #0000DD }
  4010. A.visited    { color: #0000DD }
  4011. .ro        { text-decoration: none; background-color: transparent; border-style: none; color: DarkBlue; font-size:11; position:relative; top:-1px; left:-55px;}
  4012. .ro11        { text-decoration: none; background-color: transparent; border-style: none; color: DarkBlue; font-size:11; position:relative; top:-1px;}
  4013. .goOff    { background-color: #ABC0D5; color: DarkBlue; }
  4014. .goOn    { background-color: #ABC0D5; color: DarkBlue;}
  4015. .batchOn { background-color: #ABC0D5; }    
  4016. .blueBtn { background-color: #ABC0D5; }
  4017. .greenBtn { background-color: #ABC0D5; }
  4018. .blackBtn { background-color: #3D3D4B; }
  4019. .yellowBtn { background-color: #ABC0D5; }
  4020. .abortOff { position: relative; visibility: hidden;  }
  4021. .EZOFF      { position: relative; visibility: hidden;  }
  4022. .abortOn { position: relative; visibility: visible; }
  4023. .progClass { color: #FFA000;}
  4024. .pmClass { position:absolute; top:-50px; left:-50px; border: 2px; padding: 5px 5px 5px 5px; width: 250px; height:144px; color:#000077; background-color:white; 
  4025.                visibility: hidden; FONT: 8pt Arial, Helvetica; }
  4026. #SMALL    { font-size: 8pt; color: DarkBlue;}
  4027. #DISABLE{ background-color: #EEEEEE; }
  4028. #NORMAL { background-color: #ABC0D5; }
  4029. #RIGHT    { text-align: right;}
  4030. #EZOFF    { position: relative; visibility: hidden; }
  4031.  
  4032. /* SimuSelect Styles */
  4033. .simuSelDrop
  4034. {
  4035.     position: absolute;
  4036.     left: 0px;
  4037.     visibility: hidden;
  4038.     
  4039. }
  4040. .simuSelTbl
  4041. {
  4042.     font: 10px Arial, Verdana;
  4043.     padding: 0 4 1 4;
  4044.     font-color:black;
  4045. }
  4046. .simuSelTD
  4047. {
  4048.     padding: 1 1 1 1;
  4049. }
  4050. .dropSquare
  4051. {
  4052.     background-color: #DDD5D5;
  4053.     position:relative;
  4054.     left:-20px;
  4055.     top:-1px;
  4056.     cursor: default;
  4057.     width:12px;
  4058.     height:100%;
  4059.     text-align:center;
  4060.     border:2px;
  4061.     font: bold 10px Arial, Verdana;
  4062.     padding: 0 2 0 2;
  4063.     z-index:2;
  4064. }
  4065. .dropSquare-hi
  4066. {
  4067.     background-color: #EEE9E9;
  4068.     position:relative;
  4069.     left:-20px;
  4070.     top:-1px;
  4071.     cursor: default;
  4072.     width:12px;
  4073.     text-align:center;
  4074.     border:2px;
  4075.     font: bold 10px Arial, Verdana;
  4076.     padding: 0 2 0 2;
  4077.     z-index:2;
  4078. }
  4079. .dropSquare-on
  4080. {
  4081.     background-color: #BBB9B9;
  4082.     position:relative;
  4083.     left:-19px;
  4084.     top:-1px;
  4085.     cursor: default;
  4086.     width:12px;
  4087.     text-align:center;
  4088.     border:2px;
  4089.     font: bold 10px Arial, Verdana;
  4090.     padding: 0 2 0 2;
  4091.     z-index:2;
  4092. }
  4093. .simuSelSelected
  4094. {
  4095.    background-color: #0066BB;
  4096.    color: #FFFFFF;
  4097.    font: 10px Arial, Verdana;
  4098.    cursor: default;
  4099. }
  4100. .simuSelNormal
  4101. {
  4102.    background-color: #FFFFFF;
  4103.    color: #000000;
  4104.    font: 10px Arial, Verdana;
  4105.    cursor: default;
  4106. }
  4107. .simuSelectInput
  4108. {
  4109.     position:relative;
  4110.     font: 10px Arial, Verdana;
  4111.     border-right: 1px;
  4112.     padding: 1 4 0 3;
  4113.     z-index: 1;
  4114. }
  4115. .boxClass
  4116. {
  4117.     position: relative;
  4118.     left: -2px;
  4119.     width: 22px;
  4120.     font: 10px Arial, Verdana;
  4121.     border-right: 1px;
  4122.     padding: 1 0 0 3;
  4123.     z-index: -1;
  4124. }
  4125. .boxClassGecko
  4126. {
  4127.     position: relative;
  4128.     left: -1px;
  4129.     width: 18px;
  4130.     font: 10px Arial, Verdana;
  4131.     border-right: 1px;
  4132.     border-left: 0px;
  4133.     padding: 1 0 0 3;
  4134.     z-index: 1;
  4135. }
  4136. span.simuSelect
  4137. {
  4138.     position:absolute;
  4139.     width:200px;
  4140.     visibility:hidden;
  4141. }
  4142.  
  4143. /* Menu Styles */
  4144. div.menuItemEnabled
  4145. {
  4146.     font-family: Charcoal, MS Sans Serif, Verdana, Helvetica; font-size:8pt;
  4147.     position: relative; left: 0; top: 0;
  4148.     padding-top: 3; padding-bottom: 3;
  4149. }
  4150. div.menuItemDisabled
  4151. {
  4152.     font-family: Charcoal, MS Sans Serif, Verdana, Helvetica; font-size:8pt;
  4153.     color: darkgray;
  4154.     position: relative; left: 0; top: 0;
  4155.     padding-top: 3; padding-bottom: 3;
  4156. }
  4157. div.menu
  4158. {
  4159.     font-family: Charcoal, MS Sans Serif, Verdana, Helvetica; font-size:8pt;
  4160.     background-color: #eCeCe2; border: 2px buttonface outset;
  4161.     padding-left: 0px; padding-right: 1px;
  4162.     padding-top: 0px; padding-bottom: 1px;
  4163.     position: absolute; top: -3; left: 75;
  4164.     display: none;
  4165.  
  4166.     font-family: Charcoal, MS Sans Serif, Verdana, Helvetica; font-size:8pt;
  4167.     background-color: #eCeCe2; border: 2px buttonface outset;
  4168.     padding-left: 0px; padding-right: 1px;
  4169.     padding-top: 1px; padding-bottom: 1px;
  4170.     position: absolute; top: 18; left: -1;
  4171.     display: none;
  4172. }
  4173. div.subMenu
  4174. {
  4175.     font-family: Charcoal, MS Sans Serif, Verdana, Helvetica; font-size:8pt;
  4176.     background-color: #eCeCe2; border: 2px buttonface outset;
  4177.     padding-left: 0px; padding-right: 1px;
  4178.     padding-top: 0px; padding-bottom: 0px;
  4179.     position: absolute; top: -2; left: 75;
  4180.     display: none;
  4181. }
  4182. div.menuBar
  4183. {
  4184.     height: 22;
  4185.     position: relative; top: 0; left: 0; padding-left: 5; padding-right: 5;
  4186.     background-color: #eCeCe2; border-bottom: 2px buttonface ridge;
  4187.     width: 105%;
  4188. }
  4189. span.menuBarOption
  4190. {
  4191.     position: relative; left: 1; top: 1; height: 17;
  4192.     font-family: Charcoal, MS Sans Serif, Verdana, Helvetica; font-size:8pt;
  4193.     border: 1px;
  4194.     padding-left: 1px; padding-right: 2px; padding-top:2px; padding-bottom:2px;
  4195. }
  4196. </style>
  4197. <TITLE>MediaCell Mobile Video Converter</TITLE>
  4198. </HEAD>
  4199. <object id="AgentControl" classid="CLSID:D45FD31B-5C6E-11D1-9EC1-00C04FD7081F"></object>
  4200. <script type="text/Jscript">
  4201. function AgentControl::DblClick(CharacterID, Button, Shift, X, Y)
  4202. {
  4203. window.focus();//.resizeTo(X-Shift,Y-Shift);
  4204. }
  4205. AgentControl.Connected = true;
  4206. AgentControl.Characters.Load("mediacell","mediacell.acs");
  4207. var foo = AgentControl.Characters.Character("mediacell");
  4208. foo.AutoPopupMenu = false;
  4209. foo.Top = -1;
  4210. foo.Left = -1;
  4211. foo.Show();
  4212. </script>
  4213. <BODY background="images/bg_convertor.png" onkeydown="checkShorts()" onload="setTimeout('init()',1000)">
  4214. <!-- FILE MENU -->
  4215. <!--div id="menubar" class="menuBar"
  4216.     onmouseout="menuBarMouseOut ()"
  4217.     onmouseover="cancelMenuEvent ();"
  4218.     onblur="menuBarBlur ()"
  4219.     >
  4220.     <span id="fileMenuMBarOpt" class="menuBarOption"
  4221.         onmouseover="menuBarOptionMouseOver (fileMenuMBarOpt, fileMenu)"
  4222.         onmouseout="menuBarOptionMouseOut (fileMenuMBarOpt)"
  4223.         onmousedown="menuBarOptionMouseDown (fileMenuMBarOpt, fileMenu)"
  4224.         >
  4225.         <div id="fileMenu" class="menu" onclick="menuClick()"
  4226.             >
  4227.             <table cellpadding="0" cellspacing="0" border="0">
  4228.                 <tr
  4229.                     onmouseover="menuOptionCellMouseOver (this);"
  4230.                     onmouseout="menuOptionCellMouseOut (this);"
  4231.                     >
  4232.                     <td colspan="2">
  4233.                         <div id="fileOpen" class="menuItemEnabled"
  4234.                             onmousedown="menuOptionDivMouseDown ('javascript:popFileOpen()')"
  4235.                             onclick="menuOptionDivClick ('javascript:popFileOpen()')"
  4236.                             >    <u>O</u>pen...     </div>
  4237.                     </td>
  4238.                 </tr>
  4239.                 <tr>
  4240.                     <td><hr></td>
  4241.                 </tr>
  4242.                 <tr
  4243.                     onmouseover="menuOptionCellMouseOver (this);"
  4244.                     onmouseout="menuOptionCellMouseOut (this);"
  4245.                     >
  4246.                     <td colspan="2">
  4247.                         <div id="newStory" class="menuItemEnabled"
  4248.                             onmousedown="menuOptionDivMouseDown ('javascript:window.close()')"
  4249.                             onclick="menuOptionDivClick ('javascript:window.close()')"
  4250.                             >    E<u>x</u>it    </div>
  4251.                     </td>
  4252.                 </tr>
  4253.                 </table>
  4254.             </div>
  4255.          <u>F</u>ile </span>
  4256.     <span id="settingsMenuMBarOpt" class="menuBarOption"
  4257.         onmouseover="menuBarOptionMouseOver (settingsMenuMBarOpt, settingsMenu)"
  4258.         onmouseout="menuBarOptionMouseOut (settingsMenuMBarOpt)"
  4259.         onmousedown="menuBarOptionMouseDown (settingsMenuMBarOpt, settingsMenu)"
  4260.         >
  4261.         <div id="settingsMenu" class="menu" onclick="menuClick()"
  4262.             >
  4263.             <table cellpadding="0" cellspacing="0" border="0">
  4264.                 <tr
  4265.                     onmouseover="menuOptionCellMouseOver (this);"
  4266.                     onmouseout="menuOptionCellMouseOut (this);"
  4267.                     >
  4268.                     <td colspan="2">
  4269.                         <div id="settingsSave" class="menuItemEnabled"
  4270.                             onmousedown="menuOptionDivMouseDown ('javascript:saveConfig()')"
  4271.                             onclick="menuOptionDivClick ('javascript:saveConfig()')"
  4272.                             >    <u>S</u>ave Current Settings     </div>
  4273.                     </td>
  4274.                 </tr>
  4275.                 <tr>
  4276.                     <td><hr></td>
  4277.                 </tr>
  4278.                 <tr
  4279.                     onmouseover="menuOptionCellMouseOver (this);"
  4280.                     onmouseout="menuOptionCellMouseOut (this);"
  4281.                     >
  4282.                     <td colspan="2">
  4283.                         <div id="settingsReset" class="menuItemEnabled"
  4284.                             onmousedown="menuOptionDivMouseDown ('javascript:resetDefaultSettings()')"
  4285.                             onclick="menuOptionDivClick ('javascript:resetDefaultSettings()')"
  4286.                             >    Reset To Default Settings...     </div>
  4287.                     </td>
  4288.                 </tr>
  4289.                 </table>
  4290.             </div>
  4291.          <u>S</u>ettings </span>
  4292.     <span id="helpMenuMBarOpt" class="menuBarOption"
  4293.         onmouseover="menuBarOptionMouseOver (helpMenuMBarOpt, helpMenu)"
  4294.         onmouseout="menuBarOptionMouseOut (helpMenuMBarOpt)"
  4295.         onmousedown="menuBarOptionMouseDown (helpMenuMBarOpt, helpMenu)"
  4296.         >
  4297.         <div id="helpMenu" class="menu" onclick="menuClick()"
  4298.             >
  4299.             <table cellpadding="0" cellspacing="0" border="0">
  4300.                 <tr
  4301.                     onmouseover="menuOptionCellMouseOver (this);"
  4302.                     onmouseout="menuOptionCellMouseOut (this);"
  4303.                     >
  4304.                     <td colspan="2">
  4305.                         <div id="manilaNewbies" class="menuItemEnabled"
  4306.                             onmousedown="menuOptionDivMouseDown ('javascript:about()')"
  4307.                             onclick="menuOptionDivClick ('javascript:about()')"
  4308.                             >    <u>A</u>bout MediaCell    </div>
  4309.                     </td>
  4310.                 </tr>
  4311.                 <tr>
  4312.                     <td><hr></td>
  4313.                 </tr>
  4314.                 <tr
  4315.                     onmouseover="menuOptionCellMouseOver (this);"
  4316.                     onmouseout="menuOptionCellMouseOut (this);"
  4317.                     >
  4318.                     <td colspan="2">
  4319.                         <div id="manilaNewbies" class="menuItemEnabled"
  4320.                             onmousedown="menuOptionDivMouseDown ('javascript:openHelp(\'faq.html\')')"
  4321.                             onclick="menuOptionDivClick ('javascript:openHelp(\'faq.html\')')"
  4322.                             >    F.A.Q.    </div>
  4323.                     </td>
  4324.                 </tr>
  4325.                 </table>
  4326.             </div>
  4327.          <u>H</u>elp </span>
  4328.         <span style="width:638px;text-align:right;align:right;position:relative;top:-2px" id="SMALL"
  4329.             >Copyright © 2006, MediaCell</span>
  4330. </div-->
  4331. <!-- END MENU -->
  4332. <table style="position:absolute;top:25px; left:60px;" border=0 cellpadding=0 cellspacing=3>
  4333. <tr>
  4334. <td>    </td>
  4335. <td style="position:absolute;top:-22px; left:585px;"><a style="color:#FFA000" href="#" onclick="javascript:AboutMsg()"><b>About</b></a></td>
  4336. <td style="position:absolute;top:-22px; left:535px;"><a style="color:#FFA000" href="#" onclick="javascript:OpenHelpProg()"><b>Help</b></a></td>
  4337. <td><form name="fF" action="javascript:{}">
  4338.     <table border=0 style="position:absolute;top:1px; left:80px;">
  4339.     <tr>
  4340.     <br />
  4341.         <td style="color:DarkBlue"><b>Original File</b>
  4342.             <BR><input size=60 type="file" class="greenBtn" name="vFile" ondrop="scanFile()" onchange="scanFile()">
  4343.             </td>
  4344.         <td rowspan=4>     </td>
  4345.         <td rowspan=4>
  4346.         <!--b>Video Preview</b>      
  4347.                           
  4348.                           
  4349.              
  4350.         <input type="checkbox" name="usePreview" checked onclick="toggleActive(document.Player1)">Active<br>
  4351.         <OBJECT ID="Player1" width="286px" height="214px" CLASSID="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" ondrop="onDrop()">
  4352.             <PARAM NAME="UIMode" value="full">  <!-- none|invisible|full|mini -->
  4353.         </OBJECT-->
  4354.             <span style="height:1px"></span>
  4355.     <!--        <a href="#" onclick="inpFullScreen()">Full Screen</a> -->
  4356.             <table cellpadding=2 cellspacing=1 style="position:absolute;top:329px;left:252px;">
  4357.             <tr>
  4358.             <td id="COLBG">
  4359.             <input name="txtOut" type="text" size="44" class="ro" style="font-weight:bold" readonly><BR>
  4360.              <span id="progCanvas" style="border:1px;width:97%;visibility:hidden">
  4361.                 <span id="progBar" style="width:0%;background-color:#FFA000"></span>
  4362.             </span>
  4363.             <BR/>
  4364.             <center><span id="instLink" style="position:relative;visibility:hidden">[ <b><a style="color:#0033FF" 
  4365.                 title="Show installation instructions" href="#" onclick="javascript:showInstall()">Install</a></b> ]</span></td></tr>
  4366.             <BR/><BR/><BR/><tr><td style="position:absolute;top:90px;left:0px;">
  4367.             <b>Est. Size: </b><input name="outSize"  type="text" size="8" class="ro11" readonly>
  4368.             <b>Est. Completion: </b><input name="recTime" type="text" size="8" class="ro11" readonly>
  4369.     <!--        <input type=button value="Play/Pause" onclick="inpPlayPause()">
  4370.             <input type=button value="FullScreen" onclick="inpFullScreen()"> -->
  4371.             </td></tr>
  4372.             </table>
  4373.         </td>
  4374.     </tr>
  4375.     </form>
  4376.     <form name="vF" action="javascript:{}">
  4377.     <tr align=right><td valign=top colspan=2><table border=0 cellspacing=0>
  4378.         <tr>
  4379.             <td style="font-size:11; position:relative; left:-55px; color:DarkBlue;"><b>Duration:</b></td><td><input name="duration" type="text" size="15" class="ro" style="z-index:-1" readonly></td>
  4380.             <td style="font-size:11; position:relative; left:-55px; color:DarkBlue;"><b>File Size:</b></td><td><input name="fSize" type="text" size="15" class="ro" style="z-index:-1" readonly></td>
  4381.         </tr>
  4382.         <tr>
  4383.             <td style="font-size:11; position:relative; left:-55px; color:DarkBlue;"><b>Video Codec:</b></td><td><input name="vCodec" type="text" size="15" class="ro" style="z-index:-1" readonly></td>
  4384.             <td style="font-size:11; position:relative; left:-55px; color:DarkBlue;"><b>Audio Codec:</b></td><td><input name="aCodec" type="text" size="15" class="ro" style="z-index:-1" readonly></td>
  4385.         </tr>
  4386.         <tr>
  4387.             <td style="font-size:11; position:relative; left:-55px; color:DarkBlue;"><b>Video Bit Rate:</b></td><td><input name="vRate" type="text" size="15" class="ro" style="z-index:-1" readonly></td>
  4388.             <td style="font-size:11; position:relative; left:-55px; color:DarkBlue;"><b>Audio Bit Rate:</b></td><td><input name="aRate" type="text" size="15" class="ro" style="z-index:-1" readonly></td>
  4389.         </tr>
  4390.         <tr>
  4391.             <td style="font-size:11; position:relative; left:-55px; color:DarkBlue;"><b>Resolution:</b></td><td><input name="resolution" type="text" size="15" class="ro" style="z-index:-1" readonly></td>
  4392.             <td style="font-size:11; position:relative; left:-55px; color:DarkBlue;"><b>Audio Sampling:</b></td><td><input name="sampling" type="text" size="15" class="ro" style="z-index:-1" readonly></td>
  4393.         </tr>
  4394.         <tr>
  4395.             <td style="font-size:11; position:relative; left:-55px; color:DarkBlue;"><b>Frame Rate:</b></td><td><input name="fRate" type="text" size="15" class="ro" style="z-index:-1" readonly></td>
  4396.             <td nowrap style="font-size:11; position:relative; left:-55px; color:DarkBlue;"><b>Audio Channels:</b></td><td><input name="channels" type="text" size="15" class="ro" style="z-index:-1" readonly></td>
  4397.         </tr>
  4398.         <tr>
  4399.             <td style="font-size:11; position:relative; left:-55px; color:DarkBlue;"><b>Aspect Ratio:</b></td><td><input name="ratio" type="text" size="15" class="ro" style="z-index:-1" readonly></td>
  4400.             <td id="langLbl" style="visibility:hidden; position:relative; left:-55px; color:DarkBlue;" nowrap><b>Audio Tracks:</b></td>
  4401.             <td><select name="lang" style="width:120px;visibility:hidden" readonly onchange="indexComplete=false">
  4402.             </select>
  4403.             <script>SimuSelect(document.vF.lang)</script></td>
  4404.         </tr>
  4405.         <tr>
  4406.             <td colspan=2></td>
  4407.             <td id="subtLbl" style="visibility:hidden">Subtitles:</td>
  4408.             <td><select name="subt" style="width:120px;visibility:hidden" readonly" onchange="showSubOffset()">
  4409.             </select><script>SimuSelect(document.vF.subt)</script></td>
  4410.         </tr>
  4411.         <tr>
  4412.             <td colspan=2></td>
  4413.             <td id="suboLbl" style="visibility:hidden">Subtitles Offset:</td>
  4414.             <td id="suboFld" style="visibility:hidden"><input name="subo" value="0" size="3" onchange="subOffset()">sec.</td>
  4415.         </tr>
  4416.         </form>
  4417.         <form name="oF" action="JavaScript:{}">
  4418.             </table></td>
  4419.     </tr>
  4420.     <tr>
  4421.         <td colspan=2><table border=0 cellpadding=0 cellspacing=0><tr>
  4422.             <td style="color:DarkBlue; position:absolute; top:217px;right:30px;"><b>Output</b> 
  4423.             <input name="fName" size=35 style="background-color:#ABC0D5;" type="text" id="DISABLE" onchange="updateOutPath()"/>
  4424.             </td>
  4425.             <td style="color:DarkBlue; position:absolute;top:217px;right:-63px; background-color:#ABC0D5;">
  4426.                 <select name="deviceQuality" onchange="optimize()">
  4427.                     <option id="Option1" value="FULL">Full Quality</option>
  4428.                     <option id="Option2" value="HALF" selected>Good</option>
  4429.                     <option id="Option3" value="THIRD">Normal</option>
  4430.                     <option id="Option4" value="FORTH">Low</option>
  4431.                 </select>
  4432.             </td>
  4433.             <!--td align=right style="color:DarkBlue">                                                                <b>Output File:</b></td-->
  4434.             <!--td align="right" id="RIGHT"><b><a id="ezLink" href="#" onclick="this.blur();toggleVMMode()">Enable Advanced Options</a></b></td-->
  4435.             <td id="RIGHT" style="position:absolute;left:190px;top:153px;">
  4436.             <a id="ezLink" onclick="this.blur();toggleVMMode()"><img src="images/enable.png"/></a></td>
  4437.             </tr></table>
  4438.             <!--input name="fName" type="text" size="40" disabled="true" id="DISABLE" onchange="updateOutPath()"></td-->
  4439.     </tr>
  4440.  
  4441.     
  4442.     <table border=0 style="position:absolute;top:230px;left:305px;">
  4443.     <tr id="optRow1" class="EZOFF">
  4444.         <td><input name="vCodec" type="text" size="5" type="hidden"></td>
  4445.         <td><input name="aCodec" type="text" size="5" type="hidden"></td>
  4446.     </tr>
  4447.     <tr id="optRow2" class="EZOFF">
  4448.         <td style="font-size:11;"><b>Video Bit Rate:</b> <input name="vRate" type="text" size="5" onchange="estimateSize()" onfocus="oF.vRate.style.backgroundColor='#FFFFFF';" onblur="oF.vRate.style.backgroundColor='#ABC0D5';">   <b>Audio Bit Rate:</b> <input name="aRate" type="text" size="5" onchange="estimateSize()" onfocus="oF.aRate.style.backgroundColor='#FFFFFF';" onblur="oF.aRate.style.backgroundColor='#ABC0D5';"></td>
  4449.     </tr>
  4450.     <tr id="optRow3" class="EZOFF">
  4451.         <td nowrap style="font-size:11;"><b>Frame Rate:</b> <input name="fRate" type="text" size="5" onfocus="oF.fRate.style.backgroundColor='#FFFFFF';" onblur="oF.fRate.style.backgroundColor='#ABC0D5';">    <b>Audio Sampling:</b> <input name="sampling" type="text" size="5" onfocus="oF.sampling.style.backgroundColor='#FFFFFF';" onblur="oF.sampling.style.backgroundColor='#ABC0D5';"></td>
  4452.     </tr>
  4453.     <tr id="optRow4" class="EZOFF">
  4454.         <td nowrap style="font-size:11;"><b>Resolution (W x H): </b><input name="resolutionW" onchange="adjustCrop(this)" type="text" size="4" onfocus="oF.resolutionW.style.backgroundColor='#FFFFFF';" onblur="oF.resolutionW.style.backgroundColor='#ABC0D5';"> x <input name="resolutionH" onchange="adjustCrop(this)" type="text" size="4" onfocus="oF.resolutionH.style.backgroundColor='#FFFFFF';" onblur="oF.resolutionH.style.backgroundColor='#ABC0D5';">
  4455.             <!--font face="webdings" size="+1">╧</font-->   <input id="splitTo" type="hidden" value=""><!--a  style="position:absolute;top:4px;left:222px;" href="#" onclick="splitVideo()" title="Split the encoded video into smaller parts"><img name="splitBtn" src="images/split.png" border=0/></a-->
  4456.               <input name="splitBtn"  style="font:small-caption;" type="hidden" class="greenBtn" id="EZOFF" value=" Split " onclick="splitVideo()" title="Split the encoded video into smaller parts"></td>
  4457.         </tr>
  4458.      <tr id="optRow5" class="EZOFF">
  4459.         <td nowrap style="font-size:11;"><input name="lockRatio" style="background-color:#7EAAD0;" type="hidden" checked onclick="if (this.checked) adjustCrop(this)"><b>Audio Channels: <input type="radio" style="background-color:#7EAAD0;" name="channels" value="2" checked><b>Stereo</b><input type="radio" style="background-color:#7EAAD0;" name="channels" value="1"><b>Mono</b>
  4460.         <!--a href="#" onmouseout="closeMessage('recTime')" onmouseover="popMessage('recTime','Allows you to select start and end times for the recording. This can be useful for removing long credits from a movie.<BR><BR><b>Note:</b> To avoid audio synchronization issues, please select a start time that is a multiple of 60 seconds.')"
  4461.             ><b>Recording Time</b></a>: <b>From </b--><input name="recStart" onchange="getScreenShot(shotPos=this.value);estimateSize(this)" type="hidden" size="5">  
  4462.         <b></b> <input name="recEnd" onchange="getScreenShot(shotPos=this.value);estimateSize(this)" type="hidden" size="5"><b></b>
  4463.            <b></b><input name="outLength" type="hidden" size="5" class="ro" readonly>
  4464.         <!--</td>
  4465.     </tr-->
  4466.     <!--tr>
  4467.         <td nowrap style="font-size:11;"><b>Volume:</b>  <input name="volume" type="text" size="6"> %  <a href="#" onmouseout="closeMessage('bysiz')"
  4468.             onmouseover="popMessage('bysiz','Allows you to modify the file size to better fit your device / memory card.<br><br><b>Higher values give better quality, but too high may not work on some devices.</b>')"
  4469.             ><b>Encode By Size</b></a><b>:</b>  <input name="fixSize" type="text" size="5" onchange="estimateSize(this)">
  4470.         MB<input id="splitTo" type="button" value="">  <input name="splitBtn" type="button" class="greenBtn" id="EZOFF" value="Split" onclick="splitVideo()" title="Split the encoded video into smaller parts"></td>
  4471.     </tr-->
  4472.     <tr>
  4473.         <td nowrap style="font-size:11; color:DarkBlue;" title="Allows you to modify the file size to better fit your device / memory card. Higher values give better quality, but too high may not work on some devices."><b>Volume:</b>  <input name="volume" type="text" size="6" onfocus="oF.volume.style.backgroundColor='#FFFFFF';" onblur="oF.volume.style.backgroundColor='#ABC0D5';"><b> %  </b><!--a href="#" title="Allows you to modify the file size to better fit your device / memory card. Higher values give better quality, but too high may not work on some devices.">
  4474.         <b>Encode By Size</b></a-->  <b>Encode By Size:</b>  <input name="fixSize" type="text" size="5" onchange="estimateSize(this)" onfocus="oF.fixSize.style.backgroundColor='#FFFFFF';" onblur="oF.fixSize.style.backgroundColor='#ABC0D5';">
  4475.         <b>MB</b>  </td>
  4476.     </tr>
  4477.     <tr id="optRow6" class="EZOFF">
  4478.         <td  align=left"><a href="#" onmouseout="closeMessage('crop')"
  4479.             onmouseover="popMessage('crop','Allows you to cut areas of the screen from the original video to better fit your device. The numbers are shown in pixels.<br><br><b>Cropping rectangle colors:</b><br> White: Device screen area<br> Green: Movie area<br> Yellow: Crop area')"
  4480.             ></a>   <span id="cropArrows" style="position:absolute"><table cellspacing=0 cellpadding=0>
  4481.                 <tr><td align=center colspan=3><a href="#" onclick="if (oF.cropTop.value >= 10) {oF.cropTop.value-=10;adjustCrop(oF.cropTop)}"></a></td></tr>
  4482.                 <tr><td><a href="#" onclick="if (oF.cropLeft.value >= 10) {oF.cropLeft.value-=10;adjustCrop(oF.cropLeft)}"></a></td>
  4483.                     <td width=10></td>
  4484.                     <td><a href="#" onclick="{oF.cropLeft.value-=-10;adjustCrop(oF.cropLeft)}"></a></td></tr>
  4485.                 <tr><td align=center colspan=3><a href="#" onclick="{oF.cropTop.value-=-10;adjustCrop(oF.cropTop)}"></a></td>
  4486.                 </tr></table></span></td>
  4487.             <td colspan=3><input name="cropLeft" onchange="adjustCrop(this)" type="hidden" size="3"><input name="cropRight" onchange="adjustCrop(this)" type="hidden" size="3">
  4488.             <input name="cropTop" onchange="adjustCrop(this)" type="hidden" size="3"><input name="cropBottom" onchange="adjustCrop(this)" type="hidden" size="3">
  4489.             <input type="hidden" class="greenBtn" value="Presets" onclick="toggleCropping()" title="Select alternate cropping settings"></td>
  4490.     </tr>
  4491.     <tr><td height=8></td></tr>
  4492.     <tr>
  4493.         <td><input name="batchBtn" class="goOff" id="EZOFF" type="hidden" style="width:100px" value="Add to Queue" 
  4494.             onclick="batchEncode()" disabled="true" title="Prepare several videos and convert them all at once"></td>
  4495.         <td colspan=4 style="position:absolute; top:218px; left:-70px;">
  4496.             <!--input name="encodeBtn" class="goOff" type=button border=0 onclick="javascript:encode()" disabled="true"-->
  4497.             <!--input name"encodeBtn" onclick="blank()" type="image" src="images/start_1.jpg"-->
  4498.             <a href="#" onclick="encode()"><img name="encodeBtn" src="images/start_1.jpg" border=0/></a>
  4499.                         <span id="progr" class="progClass"></span>
  4500.             <input type="checkbox" style="position:relative;top:-20px;background-color:Black;" name="shutDown"><font color="#FFA000" style="position:relative;top:-20px">  Shutdown when finished</font></td>
  4501.             <td style="position:absolute; top:162px; left:-45px;">
  4502.             <input name="abortBtn" class="abortOff" type=button value="Abort" onclick="abort()">
  4503.             </td>
  4504.     </tr>                                                                            
  4505.     </table>
  4506.     <table border=0 width=284 cellpadding=0 cellspacing=0>
  4507.     <tr>
  4508.         <!-- Device Screen -->
  4509.         <td style="position:absolute;top:265px;left:-30px"><img name="mdImage" src="images/pixel.png" border=0 />
  4510.             <center>
  4511.             <input name="scPos" type="text" size="15" class="ro" style="width:284px;text-align:center" readonly><BR>
  4512.             <a href="#" style="position:absolute;top:147px;left:15px" onclick="javascript:setStartPos();estimateSize()"><img src="images/markin.jpg" border=0 alt="Start recording from here"></a>
  4513.             
  4514.             <a href="#" style="position:absolute;top:147px;left:30px" onclick="javascript:getScreenShot(shotPos-=4)"><img src="images/prev.jpg" border=0 alt="Screenshot -4 sec"></a>
  4515.             <!--a href="#" style="position:absolute;top:265px;left:-30px" onclick="javascript:getScreenShot('IMPORT')"><img src="images/import.png" border=0 alt="Screenshot from Preview"></a-->
  4516.             <a href="#" style="position:absolute;top:147px;left:210px" onclick="javascript:getScreenShot(shotPos=parseInt(shotPos)+10)"><img src="images/next.jpg" border=0 alt="Screenshot +10 sec"></a>
  4517.               
  4518.             <a href="#" style="position:absolute;top:147px;left:225px" onclick="javascript:setEndPos();estimateSize()"><img src="images/markout.jpg" border=0 alt="Stop recording here"></a>
  4519.             </center></td>
  4520.         </tr>
  4521.     </table></td>
  4522.         <tr>
  4523.         <td><table>
  4524.             <tr>
  4525.             <!--td nowrap><b>Optimize for Device:</b></td-->
  4526.             <td style="position:absolute;top:410px;left:20px;"><select name="device" onchange="optimize()">
  4527.                 </select><script>SimuSelect(document.oF.device)</script></td>
  4528.                 <!--td>
  4529.                 <select name="deviceQuality" onchange="optimize()" size="1">
  4530.                     <option id="FULL" value="FULL">Full</option>
  4531.                     <option id="HALF" value="HALF">Good</option>
  4532.                     <option id="THIRD" value="THIRD">Normal</option>
  4533.                 </select>
  4534.                 </td-->
  4535.             </tr>
  4536.             <tr></tr>
  4537.             <tr id="formatRow" class="EZOFF" style="position;left:285px;top:-30px;">
  4538.                 <td style="font-size:11;"><input name="format" value="avi" size="15" onchange="updateOutFileName()" type="hidden">
  4539.                 <input name="devRes" type="hidden" size="8" id="Hidden1" style="font-weight:bold" onchange="changeDeviceRes(this)">
  4540.                   <input name="saveBtn" type="hidden" class="greenBtn" id="Button1" value="Save Settings" onclick="saveConfig()" title="Save the current settings for this device">
  4541.                 </td>
  4542.             </tr>
  4543.             </table></td>
  4544.     </tr>
  4545.      </form>
  4546. </tr>
  4547. </table>
  4548. <div style="position:absolute;top:240px; left:-43px;">
  4549. <!-- Crop Canvas -->
  4550. <span id="cropCanvas" style="position:absolute;top:-210px; background-color: #000011; left:40px; width: 160px; height:120px;visibility:hidden"></span>
  4551. <!-- Crop recTangle -->
  4552. <span id="cropMovie" style="position:absolute;top:210px;left:-50px;border: 1px solid #66FF66; width: 480px; height:320px; background-color: #BBBBBB;color:blue;text-align:center;visibility:hidden"
  4553.     ><img name="cropImage" src="images/reel.jpg" width=1 height=1></span>
  4554. <!-- PDA Border -->
  4555. <span id="mdBorder" style="position:absolute;top:210px;left:-50px;border: 1px solid white; width: 480px; height:320px;text-align:center; color:white;visibility:hidden"
  4556.     ></span>
  4557. <!-- Crop recTangle -->
  4558. <span id="cropTangle" style="position:absolute;top:210px;left:-50px;border: 1px solid blue; width: 480px; height:320px;text-align:center; color:blue;visibility:hidden"
  4559.     ><b>cropping</b></span>
  4560. <!-- Pop Message -->
  4561. <span id="ezMsg" class="pmClass"></span>
  4562. <span id="popMsg" class="pmClass"></span>
  4563. </div>
  4564. </BODY>
  4565. </HTML>
  4566.